From: Jürg Billeter Date: Sat, 8 Jul 2006 09:26:16 +0000 (+0000) Subject: adapt to Method API changes support signals, mark private signal handlers X-Git-Tag: VALA_0_0_1~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d445ab95531d3f3485c7bb6e4db2e2ca7a57e83f;p=thirdparty%2Fvala.git adapt to Method API changes support signals, mark private signal handlers 2006-07-08 Jürg Billeter * 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 svn path=/trunk/; revision=71 --- diff --git a/vala/ChangeLog b/vala/ChangeLog index 9c09d651b..b79b6ed62 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,3 +1,27 @@ +2006-07-08 Jürg Billeter + + * 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 * vala/valacodegenerator.vala, vala/valaclassregisterfunction.vala: diff --git a/vala/ccode/Makefile.am b/vala/ccode/Makefile.am index 6b5f945d0..3f1acbdeb 100644 --- a/vala/ccode/Makefile.am +++ b/vala/ccode/Makefile.am @@ -30,6 +30,9 @@ libvalaccode_la_SOURCES = \ valaccodecasestatement.c \ valaccodecasestatement.h \ valaccodecasestatement.vala \ + valaccodecastexpression.c \ + valaccodecastexpression.h \ + valaccodecastexpression.vala \ valaccodecommaexpression.c \ valaccodecommaexpression.h \ valaccodecommaexpression.vala \ diff --git a/vala/ccode/valaccodecastexpression.vala b/vala/ccode/valaccodecastexpression.vala new file mode 100644 index 000000000..fcf6e2ef3 --- /dev/null +++ b/vala/ccode/valaccodecastexpression.vala @@ -0,0 +1,46 @@ +/* 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 + */ + +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); + } +} diff --git a/vala/ccode/valaccodeexpression.vala b/vala/ccode/valaccodeexpression.vala index 2298b7ed5..0dec866fa 100644 --- a/vala/ccode/valaccodeexpression.vala +++ b/vala/ccode/valaccodeexpression.vala @@ -22,7 +22,8 @@ using GLib; -namespace Vala { - public abstract class CCodeExpression : CCodeNode { - } +/** + * Represents an expression node in the C code tree. + */ +public abstract class Vala.CCodeExpression : CCodeNode { } diff --git a/vala/ccode/valaccodenode.vala b/vala/ccode/valaccodenode.vala index eeb3e5cb1..d577cb426 100644 --- a/vala/ccode/valaccodenode.vala +++ b/vala/ccode/valaccodenode.vala @@ -22,8 +22,15 @@ 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); } diff --git a/vala/tests/Makefile.am b/vala/tests/Makefile.am index 97a567d39..20ef3f46d 100644 --- a/vala/tests/Makefile.am +++ b/vala/tests/Makefile.am @@ -18,4 +18,5 @@ EXTRA_DIST = \ test-015.vala \ test-016.vala \ test-017.vala \ + test-018.vala \ $(NULL) diff --git a/vala/tests/test-018.vala b/vala/tests/test-018.vala new file mode 100644 index 000000000..bacd25981 --- /dev/null +++ b/vala/tests/test-018.vala @@ -0,0 +1,52 @@ +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; + } +} diff --git a/vala/vala/parser.y b/vala/vala/parser.y index c79df977f..da436f0df 100644 --- a/vala/vala/parser.y +++ b/vala/vala/parser.y @@ -1818,16 +1818,16 @@ method_header $$->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; diff --git a/vala/vala/valacallback.vala b/vala/vala/valacallback.vala index 96cdd67f7..ab4fed2a5 100644 --- a/vala/vala/valacallback.vala +++ b/vala/vala/valacallback.vala @@ -54,7 +54,7 @@ public class Vala.Callback : DataType { } /** - * Append paramater to this callback function. + * Appends paramater to this callback function. * * @param param a formal parameter */ diff --git a/vala/vala/valaclass.vala b/vala/vala/valaclass.vala index 476710fe5..2da1d1958 100644 --- a/vala/vala/valaclass.vala +++ b/vala/vala/valaclass.vala @@ -48,6 +48,7 @@ public class Vala.Class : DataType { private string cname; private string lower_case_csuffix; + private string type_id; private bool _has_private_fields; @@ -334,6 +335,18 @@ public class Vala.Class : DataType { } } + 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; } diff --git a/vala/vala/valacodegenerator.vala b/vala/vala/valacodegenerator.vala index f1f12b82d..86b94bb68 100644 --- a/vala/vala/valacodegenerator.vala +++ b/vala/vala/valacodegenerator.vala @@ -31,6 +31,7 @@ public class Vala.CodeGenerator : CodeVisitor { */ public bool memory_management { get; set; } + Symbol root_symbol; Symbol current_symbol; Symbol current_type_symbol; @@ -58,6 +59,9 @@ public class Vala.CodeGenerator : CodeVisitor { private int next_temp_var_id = 0; + TypeReference bool_type; + TypeReference string_type; + /** * Generate and emit C code for the specified code context. * @@ -65,6 +69,14 @@ public class Vala.CodeGenerator : CodeVisitor { */ 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 (); @@ -320,7 +332,7 @@ public class Vala.CodeGenerator : CodeVisitor { var methods = cl.get_methods (); foreach (Method m in methods) { - if (!m.is_virtual && !m.is_override) { + if (!m.is_virtual && !m.overrides) { continue; } @@ -382,6 +394,41 @@ public class Vala.CodeGenerator : CodeVisitor { 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); } @@ -397,7 +444,7 @@ public class Vala.CodeGenerator : CodeVisitor { var methods = cl.get_methods (); foreach (Method m in methods) { - if (!m.is_override) { + if (!m.overrides) { continue; } @@ -815,26 +862,29 @@ public class Vala.CodeGenerator : CodeVisitor { 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); } } @@ -846,10 +896,14 @@ public class Vala.CodeGenerator : CodeVisitor { } } + 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 ()); @@ -870,7 +924,7 @@ public class Vala.CodeGenerator : CodeVisitor { 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")); @@ -882,7 +936,7 @@ public class Vala.CodeGenerator : CodeVisitor { 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)); @@ -1537,7 +1591,7 @@ public class Vala.CodeGenerator : CodeVisitor { 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 ()); @@ -1610,6 +1664,18 @@ public class Vala.CodeGenerator : CodeVisitor { 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; } } @@ -1665,9 +1731,14 @@ public class Vala.CodeGenerator : CodeVisitor { 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 @@ -1676,7 +1747,7 @@ public class Vala.CodeGenerator : CodeVisitor { ref CCodeExpression instance; if (m != null && m.instance) { var base_method = m; - if (m.is_override) { + if (m.overrides) { base_method = m.base_method; } @@ -1684,7 +1755,7 @@ public class Vala.CodeGenerator : CodeVisitor { 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 @@ -1967,12 +2038,6 @@ public class Vala.CodeGenerator : CodeVisitor { } 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) { @@ -1989,7 +2054,7 @@ public class Vala.CodeGenerator : CodeVisitor { 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) { @@ -2002,8 +2067,7 @@ public class Vala.CodeGenerator : CodeVisitor { } 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")); } diff --git a/vala/vala/valadatatype.vala b/vala/vala/valadatatype.vala index 44d6c1994..7d618350f 100644 --- a/vala/vala/valadatatype.vala +++ b/vala/vala/valadatatype.vala @@ -134,6 +134,15 @@ public abstract class Vala.DataType : CodeNode { 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 diff --git a/vala/vala/valainterfacewriter.vala b/vala/vala/valainterfacewriter.vala index 2923fe9d9..0dacb688d 100644 --- a/vala/vala/valainterfacewriter.vala +++ b/vala/vala/valainterfacewriter.vala @@ -22,329 +22,337 @@ 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 ("}"); } } diff --git a/vala/vala/valamemorymanager.vala b/vala/vala/valamemorymanager.vala index 7ac01d390..91775d79d 100644 --- a/vala/vala/valamemorymanager.vala +++ b/vala/vala/valamemorymanager.vala @@ -117,9 +117,12 @@ public class Vala.MemoryManager : CodeVisitor { 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) { diff --git a/vala/vala/valamethod.vala b/vala/vala/valamethod.vala index d318cab56..196cc7249 100644 --- a/vala/vala/valamethod.vala +++ b/vala/vala/valamethod.vala @@ -22,114 +22,202 @@ 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 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 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 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 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; } } } diff --git a/vala/vala/valasemanticanalyzer.vala b/vala/vala/valasemanticanalyzer.vala index a88804dcb..73286ba62 100644 --- a/vala/vala/valasemanticanalyzer.vala +++ b/vala/vala/valasemanticanalyzer.vala @@ -139,7 +139,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { 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; @@ -614,7 +614,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } } 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"); @@ -661,7 +664,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } 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; @@ -683,7 +690,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { 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 { @@ -702,7 +709,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } 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; } } @@ -978,7 +985,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { 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; } @@ -1008,6 +1014,32 @@ public class Vala.SemanticAnalyzer : CodeVisitor { 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) { diff --git a/vala/vala/valasignal.vala b/vala/vala/valasignal.vala index f8f6ac2b2..e8c1e6728 100644 --- a/vala/vala/valasignal.vala +++ b/vala/vala/valasignal.vala @@ -58,7 +58,7 @@ public class Vala.Signal : CodeNode { } /** - * Append parameter to signal handler. + * Appends parameter to signal handler. * * @param param a formal parameter */ diff --git a/vala/vala/valastruct.vala b/vala/vala/valastruct.vala index ef8d40ffd..4397e6df7 100644 --- a/vala/vala/valastruct.vala +++ b/vala/vala/valastruct.vala @@ -22,211 +22,272 @@ using GLib; -namespace Vala { - public class Struct : DataType { - List type_parameters; - List constants; - List fields; - List 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 type_parameters; + List constants; + List fields; + List 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 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 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 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 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; } } diff --git a/vala/vapi/glib-2.0.vala b/vala/vapi/glib-2.0.vala index 9bf68abcb..aa8188afd 100644 --- a/vala/vapi/glib-2.0.vala +++ b/vala/vapi/glib-2.0.vala @@ -20,27 +20,27 @@ * Jürg Billeter */ -[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 { } @@ -52,11 +52,11 @@ public struct short { 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 { } @@ -84,19 +84,19 @@ public struct int32 { 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 { } @@ -113,7 +113,7 @@ public struct unichar { } [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);