+2006-07-08 Jürg Billeter <j@bitron.ch>
+
+ * vala/parser.y: adapt to Method API changes
+ * vala/valasemanticanalyzer.vala: support signals, mark private signal
+ handlers as instance_last
+ * vala/valamemorymanager.vala: support signals
+ * vala/valacodegenerator.vala: support signals, methods with
+ instance_last
+ * vala/valaclass.vala: add get_type_id and get_marshaller_type_name
+ methods
+ * vala/valadatatype.vala: add get_marshaller_type_name method
+ * vala/valastruct.vala: move type_id attribute to CCode, support
+ marshaller_type_name attribute
+ * vala/valainterfacewriter.vala, vala/valamethod.vala,
+ vala/valastruct.vala, ccode/valaccodeexpression.vala,
+ ccode/valaccodenode.vala: add interface documentation, use implicit
+ namespace specification
+ * vala/valacallback.vala, vala/valasignal.vala: improve documentation
+ * ccode/valaccodecastexpression.vala: type cast in C code
+ * ccode/Makefile.am: update
+ * tests/test-018.vala: test signals
+ * tests/Makefile.am: update
+ * vapi/glib-2.0.vala: add type_id and marshaller_type_name attributes
+
2006-07-07 Jürg Billeter <j@bitron.ch>
* vala/valacodegenerator.vala, vala/valaclassregisterfunction.vala:
valaccodecasestatement.c \
valaccodecasestatement.h \
valaccodecasestatement.vala \
+ valaccodecastexpression.c \
+ valaccodecastexpression.h \
+ valaccodecastexpression.vala \
valaccodecommaexpression.c \
valaccodecommaexpression.h \
valaccodecommaexpression.vala \
--- /dev/null
+/* valaccodecastexpression.vala
+ *
+ * Copyright (C) 2006 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 type cast in the generated C code.
+ */
+public class Vala.CCodeCastExpression : CCodeExpression {
+ /**
+ * The expression to be casted.
+ */
+ public CCodeExpression! inner { get; set construct; }
+
+ /**
+ * The target type.
+ */
+ public string! type_name { get; set construct; }
+
+ public override void write (CCodeWriter! writer) {
+ writer.write_string ("(");
+ writer.write_string (type_name);
+ writer.write_string (") ");
+
+ inner.write (writer);
+ }
+}
using GLib;
-namespace Vala {
- public abstract class CCodeExpression : CCodeNode {
- }
+/**
+ * Represents an expression node in the C code tree.
+ */
+public abstract class Vala.CCodeExpression : CCodeNode {
}
using GLib;
-namespace Vala {
- public abstract class CCodeNode {
- public abstract void write (CCodeWriter writer);
- }
+/**
+ * Represents a node in the C code tree.
+ */
+public abstract class Vala.CCodeNode {
+ /**
+ * Writes this code node and all children with the specified C code
+ * writer.
+ *
+ * @param writer a C code writer
+ */
+ public abstract void write (CCodeWriter! writer);
}
test-015.vala \
test-016.vala \
test-017.vala \
+ test-018.vala \
$(NULL)
--- /dev/null
+using GLib;
+
+class Maman.Foo {
+ public signal void activated (bool b);
+
+ public void do_action () {
+ activated (false);
+ }
+}
+
+class Maman.Bar {
+ void activated (Foo foo, bool b) {
+ if (b) {
+ stdout.printf (" BAD");
+ } else {
+ stdout.printf (" 5");
+ }
+ }
+
+ public void run () {
+ stdout.printf (" 2");
+
+ var foo = new Foo ();
+
+ foo.activated += (foo, b) => {
+ if (b) {
+ stdout.printf (" BAD");
+ } else {
+ stdout.printf (" 4");
+ }
+ };
+
+ foo.activated += activated;
+
+ stdout.printf (" 3");
+
+ foo.do_action ();
+
+ stdout.printf (" 6");
+ }
+
+ static int main (int argc, string[] argv) {
+ stdout.printf ("Signal Test: 1");
+
+ var bar = new Bar ();
+ bar.run ();
+
+ stdout.printf (" 7\n");
+
+ return 0;
+ }
+}
$$->access = $3;
}
if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
- $$->instance = FALSE;
+ vala_method_set_instance ($$, FALSE);
}
if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) {
- $$->is_abstract = TRUE;
+ vala_method_set_is_abstract ($$, TRUE);
}
if (($4 & VALA_MODIFIER_VIRTUAL) == VALA_MODIFIER_VIRTUAL) {
- $$->is_virtual = TRUE;
+ vala_method_set_is_virtual ($$, TRUE);
}
if (($4 & VALA_MODIFIER_OVERRIDE) == VALA_MODIFIER_OVERRIDE) {
- $$->is_override = TRUE;
+ vala_method_set_overrides ($$, TRUE);
}
VALA_CODE_NODE($$)->attributes = $2;
}
/**
- * Append paramater to this callback function.
+ * Appends paramater to this callback function.
*
* @param param a formal parameter
*/
private string cname;
private string lower_case_csuffix;
+ private string type_id;
private bool _has_private_fields;
}
}
+ public override string get_type_id () {
+ if (type_id == null) {
+ type_id = get_upper_case_cname ("TYPE_");
+ }
+
+ return type_id;
+ }
+
+ public override string get_marshaller_type_name () {
+ return "G_TYPE_OBJECT";
+ }
+
public override bool is_reference_counting () {
return true;
}
*/
public bool memory_management { get; set; }
+ Symbol root_symbol;
Symbol current_symbol;
Symbol current_type_symbol;
private int next_temp_var_id = 0;
+ TypeReference bool_type;
+ TypeReference string_type;
+
/**
* Generate and emit C code for the specified code context.
*
*/
public void emit (CodeContext! context) {
context.find_header_cycles ();
+
+ root_symbol = context.get_root ();
+
+ bool_type = new TypeReference ();
+ bool_type.type = (DataType) root_symbol.lookup ("bool").node;
+
+ string_type = new TypeReference ();
+ string_type.type = (DataType) root_symbol.lookup ("string").node;
/* we're only interested in non-pkg source files */
var source_files = context.get_source_files ();
var methods = cl.get_methods ();
foreach (Method m in methods) {
- if (!m.is_virtual && !m.is_override) {
+ if (!m.is_virtual && !m.overrides) {
continue;
}
init_block.add_statement (new CCodeExpressionStatement (expression = cinst));
}
+ foreach (Signal sig in cl.get_signals ()) {
+ var csignew = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_signal_new"));
+ csignew.add_argument (new CCodeConstant (name = "\"%s\"".printf (sig.name)));
+ csignew.add_argument (new CCodeIdentifier (name = cl.get_upper_case_cname ("TYPE_")));
+ csignew.add_argument (new CCodeConstant (name = "G_SIGNAL_RUN_LAST"));
+ csignew.add_argument (new CCodeConstant (name = "0"));
+ csignew.add_argument (new CCodeConstant (name = "NULL"));
+ csignew.add_argument (new CCodeConstant (name = "NULL"));
+
+ /* TODO: generate marshallers */
+ string marshaller = "g_cclosure_marshal";
+
+ var marshal_arg = new CCodeIdentifier (name = marshaller);
+ csignew.add_argument (marshal_arg);
+
+ var params = sig.get_parameters ();
+ var params_len = params.length ();
+ if (sig.return_type.type == null) {
+ marshaller = "%s_VOID_".printf (marshaller);
+ csignew.add_argument (new CCodeConstant (name = "G_TYPE_NONE"));
+ } else {
+ marshaller = "%s_%s_".printf (marshaller, sig.return_type.type.get_marshaller_type_name ());
+ csignew.add_argument (new CCodeConstant (name = sig.return_type.type.get_type_id ()));
+ }
+ csignew.add_argument (new CCodeConstant (name = "%d".printf (params_len)));
+ foreach (FormalParameter param in params) {
+ marshaller = "%s_%s".printf (marshaller, param.type_reference.type.get_marshaller_type_name ());
+ csignew.add_argument (new CCodeConstant (name = param.type_reference.type.get_type_id ()));
+ }
+
+ marshal_arg.name = marshaller;
+
+ init_block.add_statement (new CCodeExpressionStatement (expression = csignew));
+ }
+
source_type_member_definition.append (class_init);
}
var methods = cl.get_methods ();
foreach (Method m in methods) {
- if (!m.is_override) {
+ if (!m.overrides) {
continue;
}
function = new CCodeFunction (name = m.get_real_cname (), return_type = m.return_type.get_cname ());
CCodeFunctionDeclarator vdeclarator = null;
+ CCodeFormalParameter instance_param = null;
+
if (m.instance) {
var this_type = new TypeReference ();
this_type.type = find_parent_type (m);
- if (!m.is_override) {
- var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
- function.add_parameter (cparam);
+ if (!m.overrides) {
+ instance_param = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
} else {
var base_type = new TypeReference ();
base_type.type = (DataType) m.base_method.symbol.parent_symbol.node;
- var cparam = new CCodeFormalParameter (type_name = base_type.get_cname (), name = "base");
- function.add_parameter (cparam);
+ instance_param = new CCodeFormalParameter (type_name = base_type.get_cname (), name = "base");
+ }
+ if (!m.instance_last) {
+ function.add_parameter (instance_param);
}
+
if (m.is_abstract || m.is_virtual) {
var vdecl = new CCodeDeclaration (type_name = m.return_type.get_cname ());
vdeclarator = new CCodeFunctionDeclarator (name = m.name);
vdecl.add_declarator (vdeclarator);
type_struct.add_declaration (vdecl);
- var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
- vdeclarator.add_parameter (cparam);
+ vdeclarator.add_parameter (instance_param);
}
}
}
}
+ if (m.instance && m.instance_last) {
+ function.add_parameter (instance_param);
+ }
+
/* real function declaration and definition not needed
* for abstract methods */
if (!m.is_abstract) {
- if (m.access == MemberAccessibility.PUBLIC && !(m.is_virtual || m.is_override)) {
+ if (m.access == MemberAccessibility.PUBLIC && !(m.is_virtual || m.overrides)) {
/* public methods need function declaration in
* header file except virtual/overridden methods */
header_type_member_declaration.append (function.copy ());
if (m.symbol.parent_symbol.node is Class) {
var cl = (Class) m.symbol.parent_symbol.node;
- if (m.is_override) {
+ if (m.overrides) {
var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
ccall.add_argument (new CCodeIdentifier (name = "base"));
cinit.append (create_method_type_check_statement (m, cl, true, "self"));
}
}
- foreach (FormalParameter param in m.parameters) {
+ foreach (FormalParameter param in m.get_parameters ()) {
var t = param.type_reference.type;
if (t != null && (t is Class || t is Interface) && !param.type_reference.is_out) {
cinit.append (create_method_type_check_statement (m, t, param.type_reference.non_null, param.name));
private void process_cmember (MemberAccess! expr, CCodeExpression pub_inst, DataType base_type) {
if (expr.symbol_reference.node is Method) {
var m = (Method) expr.symbol_reference.node;
- if (!m.is_override) {
+ if (!m.overrides) {
expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
} else {
expr.ccodenode = new CCodeIdentifier (name = m.base_method.get_cname ());
expr.ccodenode = new CCodeIdentifier (name = p.name);
}
}
+ } else if (expr.symbol_reference.node is Signal) {
+ var sig = (Signal) expr.symbol_reference.node;
+
+ var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_signal_emit_by_name"));
+
+ var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT"));
+ ccast.add_argument (pub_inst);
+ ccall.add_argument (ccast);
+
+ ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (sig.name)));
+
+ expr.ccodenode = ccall;
}
}
var param = (FormalParameter) expr.call.symbol_reference.node;
var cb = (Callback) param.type_reference.type;
params = cb.get_parameters ();
- } else {
+ } else if (expr.call.symbol_reference.node is Method) {
m = (Method) expr.call.symbol_reference.node;
params = m.get_parameters ();
+ } else {
+ var sig = (Signal) expr.call.symbol_reference.node;
+ params = sig.get_parameters ();
+
+ ccall = (CCodeFunctionCall) expr.call.ccodenode;
}
/* explicitly use strong reference as ccall gets unrefed
ref CCodeExpression instance;
if (m != null && m.instance) {
var base_method = m;
- if (m.is_override) {
+ if (m.overrides) {
base_method = m.base_method;
}
if (ma.inner == null) {
instance = new CCodeIdentifier (name = "self");
/* require casts for overriden and inherited methods */
- req_cast = m.is_override || (m.symbol.parent_symbol != current_type_symbol);
+ req_cast = m.overrides || (m.symbol.parent_symbol != current_type_symbol);
} else {
instance = (CCodeExpression) ma.inner.ccodenode;
/* reqiure casts if the type of the used instance is
} else if (a.left.symbol_reference.node is Signal) {
var sig = (Signal) a.left.symbol_reference.node;
- if (a.right.symbol_reference == null) {
- a.right.error = true;
- Report.error (a.right.source_reference, "unsupported expression for signal handler");
- return;
- }
-
var m = (Method) a.right.symbol_reference.node;
var connect_func = "g_signal_connect_object";
if (!m.instance) {
ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (sig.name)));
- ccall.add_argument (new CCodeIdentifier (name = m.get_cname ()));
+ ccall.add_argument (new CCodeCastExpression (inner = new CCodeIdentifier (name = m.get_cname ()), type_name = "GCallback"));
if (m.instance) {
if (a.right is MemberAccess) {
} else if (a.right is LambdaExpression) {
ccall.add_argument (new CCodeIdentifier (name = "self"));
}
-
- ccall.add_argument (new CCodeConstant (name = "G_CONNECT_SWAPPED"));
+ ccall.add_argument (new CCodeConstant (name = "0"));
} else {
ccall.add_argument (new CCodeConstant (name = "NULL"));
}
return null;
}
+ /**
+ * Returns the name of this data type as used in C code marshallers
+ *
+ * @return type name for marshallers
+ */
+ public virtual string get_marshaller_type_name () {
+ return null;
+ }
+
/**
* Returns the C name of this data type in upper case. Words are
* separated by underscores. The upper case C name of the namespace is
using GLib;
-namespace Vala {
- public class InterfaceWriter : CodeVisitor {
- File stream;
-
- int indent;
- /* at begin of line */
- bool bol = true;
-
- bool internal_scope = false;
-
- string current_cheader_filename;
+/**
+ * Code visitor generating Vala API file for the public interface.
+ */
+public class Vala.InterfaceWriter : CodeVisitor {
+ File stream;
+
+ int indent;
+ /* at begin of line */
+ bool bol = true;
+
+ bool internal_scope = false;
+
+ string current_cheader_filename;
- public void write_file (CodeContext context, string filename) {
- stream = File.open (filename, "w");
-
- /* we're only interested in non-pkg source files */
- foreach (SourceFile file in context.get_source_files ()) {
- if (!file.pkg) {
- file.accept (this);
- }
- }
-
- stream = null;
- }
+ /**
+ * Writes the public interface of the specified code context into the
+ * specified file.
+ *
+ * @param context a code context
+ * @param filename a relative or absolute filename
+ */
+ public void write_file (CodeContext! context, string! filename) {
+ stream = File.open (filename, "w");
- public override void visit_begin_source_file (SourceFile source_file) {
- current_cheader_filename = source_file.get_cheader_filename ();
+ /* we're only interested in non-pkg source files */
+ foreach (SourceFile file in context.get_source_files ()) {
+ if (!file.pkg) {
+ file.accept (this);
+ }
}
+
+ stream = null;
+ }
- public override void visit_begin_namespace (Namespace ns) {
- if (ns.name == null) {
- return;
- }
-
- write_indent ();
- write_string ("[CCode (cheader_filename = \"%s\")]".printf (current_cheader_filename));
- write_newline ();
+ public override void visit_begin_source_file (SourceFile source_file) {
+ current_cheader_filename = source_file.get_cheader_filename ();
+ }
- write_indent ();
- write_string ("namespace ");
- write_identifier (ns.name);
- write_begin_block ();
+ public override void visit_begin_namespace (Namespace ns) {
+ if (ns.name == null) {
+ return;
}
+
+ write_indent ();
+ write_string ("[CCode (cheader_filename = \"%s\")]".printf (current_cheader_filename));
+ write_newline ();
- public override void visit_end_namespace (Namespace ns) {
- if (ns.name == null) {
- return;
- }
-
- write_end_block ();
- write_newline ();
+ write_indent ();
+ write_string ("namespace ");
+ write_identifier (ns.name);
+ write_begin_block ();
+ }
+
+ public override void visit_end_namespace (Namespace ns) {
+ if (ns.name == null) {
+ return;
}
+
+ write_end_block ();
+ write_newline ();
+ }
- public override void visit_begin_class (Class cl) {
- if (cl.access != MemberAccessibility.PUBLIC) {
- internal_scope = true;
- return;
- }
-
- write_indent ();
- write_string ("public ");
- if (cl.is_abstract) {
- write_string ("abstract ");
- }
- write_string ("class ");
- write_identifier (cl.name);
-
- var base_types = cl.get_base_types ();
- if (base_types != null) {
- write_string (" : ");
-
- bool first = true;
- foreach (TypeReference base_type in base_types) {
- if (!first) {
- write_string (", ");
- } else {
- first = false;
- }
- write_string (base_type.type.symbol.get_full_name ());
+ public override void visit_begin_class (Class cl) {
+ if (cl.access != MemberAccessibility.PUBLIC) {
+ internal_scope = true;
+ return;
+ }
+
+ write_indent ();
+ write_string ("public ");
+ if (cl.is_abstract) {
+ write_string ("abstract ");
+ }
+ write_string ("class ");
+ write_identifier (cl.name);
+
+ var base_types = cl.get_base_types ();
+ if (base_types != null) {
+ write_string (" : ");
+
+ bool first = true;
+ foreach (TypeReference base_type in base_types) {
+ if (!first) {
+ write_string (", ");
+ } else {
+ first = false;
}
+ write_string (base_type.type.symbol.get_full_name ());
}
- write_begin_block ();
}
+ write_begin_block ();
+ }
- public override void visit_end_class (Class cl) {
- if (cl.access != MemberAccessibility.PUBLIC) {
- internal_scope = false;
- return;
- }
-
- write_end_block ();
- write_newline ();
+ public override void visit_end_class (Class cl) {
+ if (cl.access != MemberAccessibility.PUBLIC) {
+ internal_scope = false;
+ return;
}
+
+ write_end_block ();
+ write_newline ();
+ }
- public override void visit_begin_struct (Struct st) {
- if (st.access != MemberAccessibility.PUBLIC) {
- internal_scope = true;
- return;
- }
-
- write_indent ();
- write_string ("public struct ");
- write_identifier (st.name);
- write_begin_block ();
+ public override void visit_begin_struct (Struct st) {
+ if (st.access != MemberAccessibility.PUBLIC) {
+ internal_scope = true;
+ return;
}
+
+ write_indent ();
+ write_string ("public struct ");
+ write_identifier (st.name);
+ write_begin_block ();
+ }
- public override void visit_end_struct (Struct st) {
- if (st.access != MemberAccessibility.PUBLIC) {
- internal_scope = false;
- return;
- }
-
- write_end_block ();
- write_newline ();
+ public override void visit_end_struct (Struct st) {
+ if (st.access != MemberAccessibility.PUBLIC) {
+ internal_scope = false;
+ return;
}
+
+ write_end_block ();
+ write_newline ();
+ }
- public override void visit_begin_enum (Enum en) {
- if (en.access != MemberAccessibility.PUBLIC) {
- internal_scope = true;
- return;
- }
-
- write_indent ();
- write_string ("public enum ");
- write_identifier (en.name);
- write_begin_block ();
+ public override void visit_begin_enum (Enum en) {
+ if (en.access != MemberAccessibility.PUBLIC) {
+ internal_scope = true;
+ return;
}
+
+ write_indent ();
+ write_string ("public enum ");
+ write_identifier (en.name);
+ write_begin_block ();
+ }
- public override void visit_end_enum (Enum en) {
- if (en.access != MemberAccessibility.PUBLIC) {
- internal_scope = false;
- return;
- }
-
- write_end_block ();
- write_newline ();
+ public override void visit_end_enum (Enum en) {
+ if (en.access != MemberAccessibility.PUBLIC) {
+ internal_scope = false;
+ return;
}
+
+ write_end_block ();
+ write_newline ();
+ }
- public override void visit_enum_value (EnumValue ev) {
- if (internal_scope) {
- return;
- }
-
- write_indent ();
- write_identifier (ev.name);
- write_string (",");
- write_newline ();
+ public override void visit_enum_value (EnumValue ev) {
+ if (internal_scope) {
+ return;
}
+
+ write_indent ();
+ write_identifier (ev.name);
+ write_string (",");
+ write_newline ();
+ }
- public override void visit_constant (Constant c) {
- }
+ public override void visit_constant (Constant c) {
+ }
- public override void visit_field (Field f) {
- if (internal_scope || f.access != MemberAccessibility.PUBLIC) {
- return;
- }
+ public override void visit_field (Field f) {
+ if (internal_scope || f.access != MemberAccessibility.PUBLIC) {
+ return;
+ }
+
+ write_indent ();
+ write_string ("public ");
+ if (f.type_reference.is_weak) {
+ write_string ("weak ");
+ }
+ write_string (f.type_reference.type.symbol.get_full_name ());
- write_indent ();
- write_string ("public ");
- if (f.type_reference.is_weak) {
- write_string ("weak ");
- }
- write_string (f.type_reference.type.symbol.get_full_name ());
-
- var type_args = f.type_reference.get_type_arguments ();
- if (type_args != null) {
- write_string ("<");
- foreach (TypeReference type_arg in type_args) {
- if (type_arg.is_weak) {
- write_string ("weak ");
- }
- write_string (type_arg.type.symbol.get_full_name ());
+ var type_args = f.type_reference.get_type_arguments ();
+ if (type_args != null) {
+ write_string ("<");
+ foreach (TypeReference type_arg in type_args) {
+ if (type_arg.is_weak) {
+ write_string ("weak ");
}
- write_string (">");
+ write_string (type_arg.type.symbol.get_full_name ());
}
-
- write_string (" ");
- write_identifier (f.name);
- write_string (";");
- write_newline ();
+ write_string (">");
}
-
- public override void visit_begin_method (Method m) {
- if (internal_scope || m.access != MemberAccessibility.PUBLIC || m.is_override) {
- return;
- }
- write_indent ();
- write_string ("public ");
-
- if (!m.instance) {
- write_string ("static ");
- } else if (m.is_abstract) {
- write_string ("abstract ");
- } else if (m.is_virtual) {
- write_string ("virtual ");
+ write_string (" ");
+ write_identifier (f.name);
+ write_string (";");
+ write_newline ();
+ }
+
+ public override void visit_begin_method (Method m) {
+ if (internal_scope || m.access != MemberAccessibility.PUBLIC || m.overrides) {
+ return;
+ }
+
+ write_indent ();
+ write_string ("public ");
+
+ if (!m.instance) {
+ write_string ("static ");
+ } else if (m.is_abstract) {
+ write_string ("abstract ");
+ } else if (m.is_virtual) {
+ write_string ("virtual ");
+ }
+
+ var type = m.return_type.type;
+ if (type == null) {
+ write_string ("void");
+ } else {
+ if (m.return_type.is_ref) {
+ write_string ("ref ");
}
-
- var type = m.return_type.type;
- if (type == null) {
- write_string ("void");
+ write_string (m.return_type.type.symbol.get_full_name ());
+ }
+
+ write_string (" ");
+ write_identifier (m.name);
+ write_string (" (");
+
+ bool first = true;
+ foreach (FormalParameter param in m.get_parameters ()) {
+ if (!first) {
+ write_string (", ");
} else {
- if (m.return_type.is_ref) {
- write_string ("ref ");
- }
- write_string (m.return_type.type.symbol.get_full_name ());
- }
-
- write_string (" ");
- write_identifier (m.name);
- write_string (" (");
-
- bool first = true;
- foreach (FormalParameter param in m.parameters) {
- if (!first) {
- write_string (", ");
- } else {
- first = false;
- }
-
- if (param.type_reference.is_ref) {
- write_string ("ref ");
- } else if (param.type_reference.is_out) {
- write_string ("out ");
- }
- write_string (param.type_reference.type.symbol.get_full_name ());
-
- var type_args = param.type_reference.get_type_arguments ();
- if (type_args != null) {
- write_string ("<");
- foreach (TypeReference type_arg in type_args) {
- if (type_arg.is_ref) {
- write_string ("ref ");
- }
- write_string (type_arg.type.symbol.get_full_name ());
- }
- write_string (">");
- }
-
- write_string (" ");
- write_identifier (param.name);
+ first = false;
}
- write_string (");");
- write_newline ();
- }
-
- public override void visit_begin_property (Property prop) {
- if (internal_scope) {
- return;
+ if (param.type_reference.is_ref) {
+ write_string ("ref ");
+ } else if (param.type_reference.is_out) {
+ write_string ("out ");
}
+ write_string (param.type_reference.type.symbol.get_full_name ());
- write_indent ();
- write_string ("public ");
- if (prop.type_reference.is_weak) {
- write_string ("weak ");
- }
- write_string (prop.type_reference.type.symbol.get_full_name ());
-
- var type_args = prop.type_reference.get_type_arguments ();
+ var type_args = param.type_reference.get_type_arguments ();
if (type_args != null) {
write_string ("<");
foreach (TypeReference type_arg in type_args) {
- if (type_arg.is_weak) {
- write_string ("weak ");
+ if (type_arg.is_ref) {
+ write_string ("ref ");
}
write_string (type_arg.type.symbol.get_full_name ());
}
write_string (">");
}
-
+
write_string (" ");
- write_identifier (prop.name);
- write_string (" { get; set construct; }");
- write_newline ();
+ write_identifier (param.name);
}
+
+ write_string (");");
+ write_newline ();
+ }
- private void write_indent () {
- int i;
-
- if (!bol) {
- stream.putc ('\n');
- }
-
- for (i = 0; i < indent; i++) {
- stream.putc ('\t');
- }
-
- bol = false;
+ public override void visit_begin_property (Property prop) {
+ if (internal_scope) {
+ return;
}
- private void write_identifier (string s) {
- if (s == "namespace") {
- stream.putc ('@');
- }
- write_string (s);
+ write_indent ();
+ write_string ("public ");
+ if (prop.type_reference.is_weak) {
+ write_string ("weak ");
}
-
- private void write_string (string s) {
- stream.printf ("%s", s);
- bol = false;
+ write_string (prop.type_reference.type.symbol.get_full_name ());
+
+ var type_args = prop.type_reference.get_type_arguments ();
+ if (type_args != null) {
+ write_string ("<");
+ foreach (TypeReference type_arg in type_args) {
+ if (type_arg.is_weak) {
+ write_string ("weak ");
+ }
+ write_string (type_arg.type.symbol.get_full_name ());
+ }
+ write_string (">");
}
+
+ write_string (" ");
+ write_identifier (prop.name);
+ write_string (" { get; set construct; }");
+ write_newline ();
+ }
+
+ private void write_indent () {
+ int i;
- private void write_newline () {
+ if (!bol) {
stream.putc ('\n');
- bol = true;
}
- private void write_begin_block () {
- if (!bol) {
- stream.putc (' ');
- } else {
- write_indent ();
- }
- stream.putc ('{');
- write_newline ();
- indent++;
+ for (i = 0; i < indent; i++) {
+ stream.putc ('\t');
}
- private void write_end_block () {
- indent--;
+ bol = false;
+ }
+
+ private void write_identifier (string s) {
+ if (s == "namespace") {
+ stream.putc ('@');
+ }
+ write_string (s);
+ }
+
+ private void write_string (string s) {
+ stream.printf ("%s", s);
+ bol = false;
+ }
+
+ private void write_newline () {
+ stream.putc ('\n');
+ bol = true;
+ }
+
+ private void write_begin_block () {
+ if (!bol) {
+ stream.putc (' ');
+ } else {
write_indent ();
- stream.printf ("}");
}
+ stream.putc ('{');
+ write_newline ();
+ indent++;
+ }
+
+ private void write_end_block () {
+ indent--;
+ write_indent ();
+ stream.printf ("}");
}
}
var param = (FormalParameter) msym.node;
var cb = (Callback) param.type_reference.type;
params = cb.get_parameters ();
- } else {
+ } else if (msym.node is Method) {
var m = (Method) msym.node;
params = m.get_parameters ();
+ } else {
+ var sig = (Signal) msym.node;
+ params = sig.get_parameters ();
}
foreach (Expression arg in expr.argument_list) {
if (params != null) {
using GLib;
-namespace Vala {
- public class Method : CodeNode {
- public string name { get; construct; }
- public TypeReference return_type { get; construct; }
- Statement _body;
- public Statement body {
- get {
- return _body;
- }
- set {
- _body = value;
- }
+/**
+ * Represents a type or namespace method.
+ */
+public class Vala.Method : CodeNode {
+ /**
+ * The symbol name of this method.
+ */
+ public string! name { get; set construct; }
+
+ /**
+ * The return type of this method.
+ */
+ public TypeReference! return_type { get; set construct; }
+
+ public Statement body { get; set; }
+
+ /**
+ * Specifies the accessibility of this method. Public accessibility
+ * doesn't limit access. Default accessibility limits access to this
+ * program or library. Private accessibility limits access to instances
+ * of the contained type.
+ */
+ public MemberAccessibility access;
+
+ /**
+ * Specifies whether this method may only be called with an instance of
+ * the contained type.
+ */
+ public bool instance {
+ get {
+ return _instance;
}
- public MemberAccessibility access;
- public bool instance = true;
- public bool is_abstract;
- public bool is_virtual;
- public bool is_override;
- public List<FormalParameter> parameters;
- public string cname;
- public bool returns_modified_pointer;
- public bool instance_last;
-
- /* reference must be weak as virtual methods set base_method to themselves */
- public weak Method base_method;
-
- public FormalParameter this_parameter;
-
- public static ref Method new (string name, TypeReference return_type, SourceReference source) {
- return (new Method (name = name, return_type = return_type, source_reference = source));
+ set {
+ _instance = value;
}
+ }
+
+ /**
+ * Specifies whether this method is abstract. Abstract methods have no
+ * body, may only be specified within abstract classes, and must be
+ * overriden by derived non-abstract classes.
+ */
+ public bool is_abstract { get; set; }
+
+ /**
+ * Specifies whether this method is virtual. Virtual methods may be
+ * overridden by derived classes.
+ */
+ public bool is_virtual { get; set; }
+
+ /**
+ * Specifies whether this method overrides a virtual or abstract method
+ * of a base type.
+ */
+ public bool overrides { get; set; }
+
+ /**
+ * Specifies whether the C method returns a new instance pointer which
+ * may be different from the previous instance pointer. Only valid for
+ * imported methods.
+ */
+ public bool returns_modified_pointer { get; set; }
+
+ /**
+ * Specifies whether the instance pointer should be passed as the first
+ * or as the last argument in C code. Defaults to first.
+ */
+ public bool instance_last { get; set; }
+
+ /**
+ * Specifies the virtual or abstract method this method overrides.
+ * Reference must be weak as virtual methods set base_method to
+ * themselves.
+ */
+ public weak Method base_method { get; set; }
+
+ /**
+ * Specifies the generated `this' parameter for instance methods.
+ */
+ public FormalParameter this_parameter { get; set; }
+
+ private bool _instance = true;
+ private List<FormalParameter> parameters;
+ private string cname;
+
+ /**
+ * Creates a new method.
+ *
+ * @param name method name
+ * @param return_type method return type
+ * @param source reference to source code
+ * @return newly created method
+ */
+ public static ref Method! new (string! name, TypeReference! return_type, SourceReference source) {
+ return (new Method (name = name, return_type = return_type, source_reference = source));
+ }
+
+ /**
+ * Appends parameter to this method.
+ *
+ * @param param a formal parameter
+ */
+ public void add_parameter (FormalParameter! param) {
+ parameters.append (param);
+ }
+
+ /**
+ * Returns copy of the list of method parameters.
+ *
+ * @return parameter list
+ */
+ public ref List<FormalParameter> get_parameters () {
+ return parameters.copy ();
+ }
+
+ public override void accept (CodeVisitor visitor) {
+ visitor.visit_begin_method (this);
- public void add_parameter (FormalParameter param) {
- parameters.append (param);
- }
+ return_type.accept (visitor);
- public ref List<FormalParameter> get_parameters () {
- return parameters.copy ();
+ foreach (FormalParameter param in parameters) {
+ param.accept (visitor);
}
- public override void accept (CodeVisitor visitor) {
- visitor.visit_begin_method (this);
-
- return_type.accept (visitor);
-
- foreach (FormalParameter param in parameters) {
- param.accept (visitor);
- }
-
- if (body != null) {
- body.accept (visitor);
- }
-
- visitor.visit_end_method (this);
+ if (body != null) {
+ body.accept (visitor);
}
- public string get_cname () {
- if (cname == null) {
- var parent = symbol.parent_symbol.node;
- if (parent is DataType) {
- cname = "%s_%s".printf (((DataType) parent).get_lower_case_cname (null), name);
- } else if (parent is Namespace) {
- cname = "%s%s".printf (((Namespace) parent).get_lower_case_cprefix (), name);
- } else {
- cname = name;
- }
- }
- return cname;
- }
+ visitor.visit_end_method (this);
+ }
- public ref string get_real_cname () {
- if (is_virtual || is_override) {
- var parent = (Class) symbol.parent_symbol.node;
- return "%s_real_%s".printf (parent.get_lower_case_cname (null), name);
+ /**
+ * Returns the interface name of this method as it is used in C code.
+ *
+ * @return the name to be used in C code
+ */
+ public string! get_cname () {
+ if (cname == null) {
+ var parent = symbol.parent_symbol.node;
+ if (parent is DataType) {
+ cname = "%s_%s".printf (((DataType) parent).get_lower_case_cname (null), name);
+ } else if (parent is Namespace) {
+ cname = "%s%s".printf (((Namespace) parent).get_lower_case_cprefix (), name);
} else {
- return get_cname ();
+ cname = name;
}
}
-
- public void set_cname (string cname) {
- this.cname = cname;
+ return cname;
+ }
+
+ /**
+ * Returns the implementation name of this data type as it is used in C
+ * code.
+ *
+ * @return the name to be used in C code
+ */
+ public ref string! get_real_cname () {
+ if (is_virtual || overrides) {
+ var parent = (Class) symbol.parent_symbol.node;
+ return "%s_real_%s".printf (parent.get_lower_case_cname (null), name);
+ } else {
+ return get_cname ();
}
-
- void process_ccode_attribute (Attribute a) {
- foreach (NamedArgument arg in a.args) {
- if (arg.name == "cname") {
- /* this will already be checked during semantic analysis */
- if (arg.argument is LiteralExpression) {
- var lit = ((LiteralExpression) arg.argument).literal;
- if (lit is StringLiteral) {
- set_cname (((StringLiteral) lit).eval ());
- }
+ }
+
+ private void set_cname (string cname) {
+ this.cname = cname;
+ }
+
+ private void process_ccode_attribute (Attribute a) {
+ foreach (NamedArgument arg in a.args) {
+ if (arg.name == "cname") {
+ /* this will already be checked during semantic analysis */
+ if (arg.argument is LiteralExpression) {
+ var lit = ((LiteralExpression) arg.argument).literal;
+ if (lit is StringLiteral) {
+ set_cname (((StringLiteral) lit).eval ());
}
}
}
}
-
- public void process_attributes () {
- foreach (Attribute a in attributes) {
- if (a.name == "CCode") {
- process_ccode_attribute (a);
- } else if (a.name == "ReturnsModifiedPointer") {
- returns_modified_pointer = true;
- } else if (a.name == "InstanceLast") {
- instance_last = true;
- } else if (a.name == "FloatingReference") {
- return_type.floating_reference = true;
- }
+ }
+
+ /**
+ * 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 == "ReturnsModifiedPointer") {
+ returns_modified_pointer = true;
+ } else if (a.name == "InstanceLast") {
+ instance_last = true;
+ } else if (a.name == "FloatingReference") {
+ return_type.floating_reference = true;
}
}
}
current_return_type = up_method.return_type;
}
- if (m.is_virtual || m.is_override) {
+ if (m.is_virtual || m.overrides) {
if (current_symbol.node is Class) {
var cl = (Class) current_symbol.node;
Class base_class;
}
} else if (msym.node is Method) {
var m = (Method) msym.node;
- params = m.parameters;
+ params = m.get_parameters ();
+ } else if (msym.node is Signal) {
+ var sig = (Signal) msym.node;
+ params = sig.get_parameters ();
} else {
expr.error = true;
Report.error (expr.source_reference, "invocation not supported in this context");
} else if (msym.node is Method) {
var m = (Method) msym.node;
ret_type = m.return_type;
- params = m.parameters;
+ params = m.get_parameters ();
+ } else if (msym.node is Signal) {
+ var sig = (Signal) msym.node;
+ ret_type = sig.return_type;
+ params = sig.get_parameters ();
}
expr.static_type = ret_type;
if (arg_it == null) {
if (param.default_expression == null) {
- Report.error (expr.source_reference, "Method `%s' does not take %d arguments".printf (msym.get_full_name (), expr.argument_list.length ()));
+ Report.error (expr.source_reference, "Too few arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), expr.argument_list.length ()));
return;
}
} else {
}
if (!ellipsis && arg_it != null) {
- Report.error (expr.source_reference, "Method `%s' does not take %d arguments".printf (msym.get_full_name (), expr.argument_list.length ()));
+ Report.error (expr.source_reference, "Too many arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), expr.argument_list.length ()));
return;
}
}
l.method.body = block;
} else {
l.method.body = l.statement_body;
- l.method.body.symbol = new Symbol (node = l.method.body);
l.method.body.symbol.parent_symbol = l.method.symbol;
}
if (ma.symbol_reference.node is Signal) {
var sig = (Signal) ma.symbol_reference.node;
+
+ if (a.right.symbol_reference == null) {
+ a.right.error = true;
+ Report.error (a.right.source_reference, "unsupported expression for signal handler");
+ return;
+ }
+
+ var m = (Method) a.right.symbol_reference.node;
+
+ if (m.instance && m.access == MemberAccessibility.PUBLIC) {
+ /* TODO: generate wrapper function */
+
+ ma.error = true;
+ Report.error (a.right.source_reference, "public instance methods not yet supported as signal handlers");
+ return;
+ }
+
+ if (m.instance) {
+ /* instance signal handlers must have the self
+ * parameter at the end
+ * do not use G_CONNECT_SWAPPED as this would
+ * rearrange the parameters for instance
+ * methods and non-instance methods
+ */
+ m.instance_last = true;
+ }
} else if (ma.symbol_reference.node is Property) {
var prop = (Property) ma.symbol_reference.node;
} else if (ma.symbol_reference.node is VariableDeclarator && a.right.static_type == null) {
}
/**
- * Append parameter to signal handler.
+ * Appends parameter to signal handler.
*
* @param param a formal parameter
*/
using GLib;
-namespace Vala {
- public class Struct : DataType {
- List<TypeParameter> type_parameters;
- List<Constant> constants;
- List<Field> fields;
- List<Method> methods;
-
- string cname;
- string dup_function;
- string free_function;
- string type_id;
- string lower_case_csuffix;
- bool reference_type;
-
- public static ref Struct new (string! name, SourceReference source) {
- return (new Struct (name = name, source_reference = source));
- }
+/**
+ * Represents a struct declaration in the source code.
+ */
+public class Vala.Struct : DataType {
+ List<TypeParameter> type_parameters;
+ List<Constant> constants;
+ List<Field> fields;
+ List<Method> methods;
+
+ string cname;
+ string dup_function;
+ string free_function;
+ string type_id;
+ string lower_case_csuffix;
+ bool reference_type;
+ string marshaller_type_name;
+
+ /**
+ * Creates a new struct.
+ *
+ * @param name type name
+ * @param source reference to source code
+ * @return newly created struct
+ */
+ public static ref Struct! new (string! name, SourceReference source) {
+ return (new Struct (name = name, source_reference = source));
+ }
- public void add_type_parameter (TypeParameter! p) {
- type_parameters.append (p);
- p.type = this;
- }
+ /**
+ * 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<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);
- public void add_constant (Constant! c) {
- constants.append (c);
- }
+ methods.append (m);
+ }
+
+ /**
+ * Returns a copy of the list of methods.
+ *
+ * @return list of methods
+ */
+ public ref List<Method> get_methods () {
+ return methods.copy ();
+ }
+
+ public override void accept (CodeVisitor! visitor) {
+ visitor.visit_begin_struct (this);
- public void add_field (Field! f) {
- fields.append (f);
+ foreach (TypeParameter p in type_parameters) {
+ p.accept (visitor);
}
- public ref List<Field> get_fields () {
- return fields.copy ();
+ foreach (Field f in fields) {
+ f.accept (visitor);
}
- public void add_method (Method! m) {
- return_if_fail (m != null);
-
- methods.append (m);
+ foreach (Constant c in constants) {
+ c.accept (visitor);
}
- public ref List<Method> get_methods () {
- return methods.copy ();
+ foreach (Method m in methods) {
+ m.accept (visitor);
}
-
- 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 () {
- if (cname == null) {
- cname = "%s%s".printf (@namespace.get_cprefix (), name);
- }
- return cname;
- }
-
- public void set_cname (string! cname) {
- this.cname = cname;
- }
-
- public string get_lower_case_csuffix () {
- if (lower_case_csuffix == null) {
- lower_case_csuffix = Namespace.camel_case_to_lower_case (name);
- }
- return lower_case_csuffix;
- }
-
- public 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 ());
+ visitor.visit_end_struct (this);
+ }
+
+ public override string get_cname () {
+ if (cname == null) {
+ cname = "%s%s".printf (@namespace.get_cprefix (), name);
}
-
- public override ref string get_upper_case_cname (string infix) {
- return get_lower_case_cname (infix).up ();
+ return cname;
+ }
+
+ private void set_cname (string! cname) {
+ this.cname = cname;
+ }
+
+ private string get_lower_case_csuffix () {
+ if (lower_case_csuffix == null) {
+ lower_case_csuffix = Namespace.camel_case_to_lower_case (name);
}
-
- public override bool is_reference_type () {
- return reference_type;
+ 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 = "";
}
-
- private void process_ccode_attribute (Attribute! a) {
- foreach (NamedArgument arg in a.args) {
- if (arg.name == "cname") {
- /* this will already be checked during semantic analysis */
- if (arg.argument is LiteralExpression) {
- var lit = ((LiteralExpression) arg.argument).literal;
- if (lit is StringLiteral) {
- set_cname (((StringLiteral) lit).eval ());
- }
- }
- } else if (arg.name == "cheader_filename") {
- /* this will already be checked during semantic analysis */
- if (arg.argument is LiteralExpression) {
- var lit = ((LiteralExpression) arg.argument).literal;
- if (lit is StringLiteral) {
- var val = ((StringLiteral) lit).eval ();
- foreach (string filename in val.split (",", 0)) {
- add_cheader_filename (filename);
- }
- }
+ 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;
+ }
+
+ private void process_ccode_attribute (Attribute! a) {
+ foreach (NamedArgument arg in a.args) {
+ if (arg.name == "cname") {
+ /* this will already be checked during semantic analysis */
+ if (arg.argument is LiteralExpression) {
+ var lit = ((LiteralExpression) arg.argument).literal;
+ if (lit is StringLiteral) {
+ set_cname (((StringLiteral) lit).eval ());
}
}
- }
- }
-
- private void process_ref_type_attribute (Attribute! a) {
- reference_type = true;
- foreach (NamedArgument arg in a.args) {
- if (arg.name == "dup_function") {
- /* this will already be checked during semantic analysis */
- if (arg.argument is LiteralExpression) {
- var lit = ((LiteralExpression) arg.argument).literal;
- if (lit is StringLiteral) {
- set_dup_function (((StringLiteral) lit).eval ());
+ } else if (arg.name == "cheader_filename") {
+ /* this will already be checked during semantic analysis */
+ if (arg.argument is LiteralExpression) {
+ var lit = ((LiteralExpression) arg.argument).literal;
+ if (lit is StringLiteral) {
+ var val = ((StringLiteral) lit).eval ();
+ foreach (string filename in val.split (",", 0)) {
+ add_cheader_filename (filename);
}
}
- } else if (arg.name == "free_function") {
- /* this will already be checked during semantic analysis */
- if (arg.argument is LiteralExpression) {
- var lit = ((LiteralExpression) arg.argument).literal;
- if (lit is StringLiteral) {
- set_free_function (((StringLiteral) lit).eval ());
- }
+ }
+ } else if (arg.name == "type_id") {
+ /* this will already be checked during semantic analysis */
+ if (arg.argument is LiteralExpression) {
+ var lit = ((LiteralExpression) arg.argument).literal;
+ if (lit is StringLiteral) {
+ set_type_id (((StringLiteral) lit).eval ());
}
- } else if (arg.name == "type_id") {
- /* this will already be checked during semantic analysis */
- if (arg.argument is LiteralExpression) {
- var lit = ((LiteralExpression) arg.argument).literal;
- if (lit is StringLiteral) {
- set_type_id (((StringLiteral) lit).eval ());
- }
+ }
+ } else if (arg.name == "marshaller_type_name") {
+ /* this will already be checked during semantic analysis */
+ if (arg.argument is LiteralExpression) {
+ var lit = ((LiteralExpression) arg.argument).literal;
+ if (lit is StringLiteral) {
+ set_marshaller_type_name (((StringLiteral) lit).eval ());
}
}
}
}
-
- 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);
+ }
+
+ private void process_ref_type_attribute (Attribute! a) {
+ reference_type = true;
+ foreach (NamedArgument arg in a.args) {
+ if (arg.name == "dup_function") {
+ /* this will already be checked during semantic analysis */
+ if (arg.argument is LiteralExpression) {
+ var lit = ((LiteralExpression) arg.argument).literal;
+ if (lit is StringLiteral) {
+ set_dup_function (((StringLiteral) lit).eval ());
+ }
+ }
+ } else if (arg.name == "free_function") {
+ /* this will already be checked during semantic analysis */
+ if (arg.argument is LiteralExpression) {
+ var lit = ((LiteralExpression) arg.argument).literal;
+ if (lit is StringLiteral) {
+ set_free_function (((StringLiteral) lit).eval ());
+ }
}
}
}
-
- 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 ()));
+ }
+
+ /**
+ * 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);
}
- 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;
+ }
+
+ 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 ()));
}
-
- public void set_free_function (string! name) {
- this.free_function = 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 ()));
}
-
- public override string get_type_id () {
- if (type_id == null) {
- Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (symbol.get_full_name ()));
- }
- return type_id;
+ return free_function;
+ }
+
+ private void set_free_function (string! name) {
+ this.free_function = name;
+ }
+
+ public override string get_type_id () {
+ if (type_id == null) {
+ Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (symbol.get_full_name ()));
}
-
- public void set_type_id (string! name) {
- this.type_id = name;
+ return type_id;
+ }
+
+ private void set_type_id (string! name) {
+ this.type_id = name;
+ }
+
+ public override string get_marshaller_type_name () {
+ if (marshaller_type_name == null) {
+ 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;
}
}
* Jürg Billeter <j@bitron.ch>
*/
-[CCode (cname = "gboolean", cheader_filename = "glib.h")]
+[CCode (cname = "gboolean", cheader_filename = "glib.h", type_id = "G_TYPE_BOOLEAN", marshaller_type_name = "BOOLEAN")]
public struct bool {
}
-[CCode (cname = "gpointer", cheader_filename = "glib.h")]
+[CCode (cname = "gpointer", cheader_filename = "glib.h", type_id = "G_TYPE_POINTER", marshaller_type_name = "POINTER")]
public struct pointer {
}
-[CCode (cheader_filename = "glib.h")]
+[CCode (cheader_filename = "glib.h", type_id = "G_TYPE_CHAR", marshaller_type_name = "CHAR")]
public struct char {
}
-[CCode (cname = "unsigned char", cheader_filename = "glib.h")]
+[CCode (cname = "unsigned char", cheader_filename = "glib.h", type_id = "G_TYPE_UCHAR", marshaller_type_name = "UCHAR")]
public struct uchar {
}
-[CCode (cheader_filename = "glib.h")]
+[CCode (cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT")]
public struct int {
}
-[CCode (cname = "unsigned int", cheader_filename = "glib.h")]
+[CCode (cname = "unsigned int", cheader_filename = "glib.h", type_id = "G_TYPE_UINT", marshaller_type_name = "UINT")]
public struct uint {
}
public struct ushort {
}
-[CCode (cheader_filename = "glib.h")]
+[CCode (cheader_filename = "glib.h", type_id = "G_TYPE_LONG", marshaller_type_name = "LONG")]
public struct long {
}
-[CCode (cname = "unsigned long", cheader_filename = "glib.h")]
+[CCode (cname = "unsigned long", cheader_filename = "glib.h", type_id = "G_TYPE_ULONG", marshaller_type_name = "ULONG")]
public struct ulong {
}
public struct uint32 {
}
-[CCode (cname = "gint64", cheader_filename = "glib.h")]
+[CCode (cname = "gint64", cheader_filename = "glib.h", type_id = "G_TYPE_INT64", marshaller_type_name = "INT64")]
public struct int64 {
}
-[CCode (cname = "guint64", cheader_filename = "glib.h")]
+[CCode (cname = "guint64", cheader_filename = "glib.h", type_id = "G_TYPE_UINT64", marshaller_type_name = "UINT64")]
public struct uint64 {
}
-[CCode (cname = "float", cheader_filename = "glib.h")]
+[CCode (cname = "float", cheader_filename = "glib.h", type_id = "G_TYPE_FLOAT", marshaller_type_name = "FLOAT")]
public struct float {
}
-[CCode (cname = "double", cheader_filename = "glib.h")]
+[CCode (cname = "double", cheader_filename = "glib.h", type_id = "G_TYPE_DOUBLE", marshaller_type_name = "DOUBLE")]
public struct double {
}
}
[ReferenceType (dup_function = "g_strdup", free_function = "g_free", type_id = "G_TYPE_STRING", ref_function = "g_strdup")]
-[CCode (cname = "char", cheader_filename = "string.h,glib.h")]
+[CCode (cname = "char", cheader_filename = "string.h,glib.h", type_id = "G_TYPE_STRING", marshaller_type_name = "STRING")]
public struct string {
[CCode (cname = "g_str_has_suffix")]
public bool has_suffix (string suffix);