From 612e05c3a869ef863bdd40784de6acd107fb2289 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=BCrg=20Billeter?= Date: Mon, 30 Apr 2007 09:27:07 +0000 Subject: [PATCH] add basic support for flags, fixes bug 434511 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 2007-04-30 Jürg Billeter * vala/parser.y, vala/valasymbolbuilder.vala, vala/valaattributeprocessor.vala, vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala, vala/valainterfacewriter.vala, vala/valaflags.vala: add basic support for flags, fixes bug 434511 svn path=/trunk/; revision=292 --- vala/ChangeLog | 7 ++++ vala/vala/parser.y | 39 ++++++++++++++++- vala/vala/valaattributeprocessor.vala | 4 ++ vala/vala/valacodegenerator.vala | 22 +++++++++- vala/vala/valaenum.vala | 2 +- vala/vala/valaflags.vala | 79 ++++++++++++++++++++++++++++++----- vala/vala/valainterfacewriter.vala | 44 +++++++++++++++++-- vala/vala/valasemanticanalyzer.vala | 2 +- vala/vala/valasymbolbuilder.vala | 32 +++++++++++--- 9 files changed, 207 insertions(+), 24 deletions(-) diff --git a/vala/ChangeLog b/vala/ChangeLog index 6c3d2d1..c7971b5 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,5 +1,12 @@ 2007-04-30 Jürg Billeter + * vala/parser.y, vala/valasymbolbuilder.vala, + vala/valaattributeprocessor.vala, vala/valasemanticanalyzer.vala, + vala/valacodegenerator.vala, vala/valainterfacewriter.vala, + vala/valaflags.vala: add basic support for flags, fixes bug 434511 + +2007-04-30 Jürg Billeter + * vala/valasemanticanalyzer.vala: check that void return values are not used, fixes bug 434503 diff --git a/vala/vala/parser.y b/vala/vala/parser.y index 229683c..06e69a3 100644 --- a/vala/vala/parser.y +++ b/vala/vala/parser.y @@ -332,6 +332,10 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg); %type enum_member_declarations %type enum_member_declaration %type flags_declaration +%type flags_body +%type opt_flags_member_declarations +%type flags_member_declarations +%type flags_member_declaration %type callback_declaration %type constant_declaration %type field_declaration @@ -3155,29 +3159,62 @@ flags_declaration name = $6; } + GList *l; ValaSourceReference *src = src_com(@5, $1); $$ = vala_flags_new (name, src); g_free (name); g_object_unref (src); + + VALA_CODE_NODE($$)->attributes = $2; + + if ($3 != 0) { + VALA_DATA_TYPE($$)->access = $3; + } + for (l = $7; l != NULL; l = l->next) { + vala_flags_add_value ($$, l->data); + g_object_unref (l->data); + } } ; flags_body : OPEN_BRACE opt_flags_member_declarations CLOSE_BRACE + { + $$ = $2; + } ; opt_flags_member_declarations : /* empty */ - | flags_member_declarations + { + $$ = NULL; + } + | flags_member_declarations opt_comma ; flags_member_declarations : flags_member_declaration + { + $$ = g_list_append (NULL, $1); + } | flags_member_declarations COMMA flags_member_declaration + { + $$ = g_list_append ($1, $3); + } ; flags_member_declaration : opt_attributes identifier + { + $$ = vala_flags_value_new ($2); + g_free ($2); + } + | opt_attributes identifier ASSIGN expression + { + $$ = vala_flags_value_new_with_value ($2, $4); + g_free ($2); + g_object_unref ($4); + } ; callback_declaration diff --git a/vala/vala/valaattributeprocessor.vala b/vala/vala/valaattributeprocessor.vala index f1fa963..2c4901f 100644 --- a/vala/vala/valaattributeprocessor.vala +++ b/vala/vala/valaattributeprocessor.vala @@ -56,6 +56,10 @@ public class Vala.AttributeProcessor : CodeVisitor { en.process_attributes (); } + public override void visit_begin_flags (Flags! fl) { + fl.process_attributes (); + } + public override void visit_begin_method (Method! m) { m.process_attributes (); } diff --git a/vala/vala/valacodegenerator.vala b/vala/vala/valacodegenerator.vala index 4b79237..8a88071 100644 --- a/vala/vala/valacodegenerator.vala +++ b/vala/vala/valacodegenerator.vala @@ -1065,7 +1065,7 @@ public class Vala.CodeGenerator : CodeVisitor { source_type_member_definition.append (base_init); } - + public override void visit_begin_enum (Enum! en) { cenum = new CCodeEnum (en.get_cname ()); @@ -1086,6 +1086,26 @@ public class Vala.CodeGenerator : CodeVisitor { cenum.add_value (ev.get_cname (), val); } + public override void visit_begin_flags (Flags! fl) { + cenum = new CCodeEnum (fl.get_cname ()); + + if (fl.source_reference.comment != null) { + header_type_definition.append (new CCodeComment (fl.source_reference.comment)); + } + header_type_definition.append (cenum); + } + + public override void visit_flags_value (FlagsValue! fv) { + string val; + if (fv.value is LiteralExpression) { + var lit = ((LiteralExpression) fv.value).literal; + if (lit is IntegerLiteral) { + val = ((IntegerLiteral) lit).value; + } + } + cenum.add_value (fv.get_cname (), val); + } + public override void visit_end_callback (Callback! cb) { var cfundecl = new CCodeFunctionDeclarator (cb.get_cname ()); foreach (FormalParameter param in cb.get_parameters ()) { diff --git a/vala/vala/valaenum.vala b/vala/vala/valaenum.vala index 341f450..a759c00 100644 --- a/vala/vala/valaenum.vala +++ b/vala/vala/valaenum.vala @@ -148,5 +148,5 @@ public class Vala.Enum : DataType { public override string get_default_value () { return "0"; - } + } } diff --git a/vala/vala/valaflags.vala b/vala/vala/valaflags.vala index f14ebff..d47cb8b 100644 --- a/vala/vala/valaflags.vala +++ b/vala/vala/valaflags.vala @@ -1,6 +1,6 @@ /* valaflags.vala * - * Copyright (C) 2006 Jürg Billeter + * Copyright (C) 2006-2007 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,8 +26,9 @@ using GLib; * Represents a flags declaration in the source code. */ public class Vala.Flags : DataType { - List values; - string cname; + private List values; + private string cname; + private string cprefix; /** * Creates a new flags. @@ -36,11 +37,9 @@ public class Vala.Flags : DataType { * @param source reference to source code * @return newly created flags */ - public Flags (string! _name, SourceReference source) { - name = _name; - source_reference = source; + public Flags (construct string! name, construct SourceReference source_reference = null) { } - + /** * Appends the specified flags value to the list of values. * @@ -49,10 +48,10 @@ public class Vala.Flags : DataType { public void add_value (FlagsValue! value) { values.append (value); } - + public override void accept (CodeVisitor! visitor) { visitor.visit_begin_flags (this); - + foreach (FlagsValue value in values) { value.accept (visitor); } @@ -66,7 +65,7 @@ public class Vala.Flags : DataType { } return cname; } - + public override ref string get_upper_case_cname (string infix) { return "%s%s".printf (@namespace.get_lower_case_cprefix (), Namespace.camel_case_to_lower_case (name)).up (); } @@ -75,6 +74,64 @@ public class Vala.Flags : DataType { return false; } + private void set_cname (string! cname) { + this.cname = cname; + } + + /** + * Returns the string to be prepended to the name of members of this + * enum when used in C code. + * + * @return the prefix to be used in C code + */ + public string! get_cprefix () { + if (cprefix == null) { + cprefix = "%s_".printf (get_upper_case_cname (null)); + } + return cprefix; + } + + /** + * Sets the string to be prepended to the name of members of this enum + * when used in C code. + * + * @param cprefix the prefix to be used in C code + */ + public void set_cprefix (string! cprefix) { + this.cprefix = cprefix; + } + + private void process_ccode_attribute (Attribute! a) { + if (a.has_argument ("cname")) { + set_cname (a.get_string ("cname")); + } + if (a.has_argument ("cprefix")) { + set_cprefix (a.get_string ("cprefix")); + } + if (a.has_argument ("cheader_filename")) { + var val = a.get_string ("cheader_filename"); + foreach (string filename in val.split (",")) { + add_cheader_filename (filename); + } + } + } + + /** + * Process all associated attributes. + */ + public void process_attributes () { + foreach (Attribute a in attributes) { + if (a.name == "CCode") { + process_ccode_attribute (a); + } + } + } + + public override string get_type_id () { + // FIXME: use GType-registered flags + return "G_TYPE_INT"; + } + public override string get_marshaller_type_name () { return "FLAGS"; } @@ -82,7 +139,7 @@ public class Vala.Flags : DataType { public override string get_get_value_function () { return "g_value_get_flags"; } - + public override string get_set_value_function () { return "g_value_set_flags"; } diff --git a/vala/vala/valainterfacewriter.vala b/vala/vala/valainterfacewriter.vala index dbee461..e518ffc 100644 --- a/vala/vala/valainterfacewriter.vala +++ b/vala/vala/valainterfacewriter.vala @@ -199,10 +199,10 @@ public class Vala.InterfaceWriter : CodeVisitor { internal_scope = true; return; } - + write_indent (); write_string ("[CCode (cprefix = \"%s\")]".printf (en.get_cprefix ())); - + write_indent (); write_string ("public enum "); write_identifier (en.name); @@ -214,7 +214,7 @@ public class Vala.InterfaceWriter : CodeVisitor { internal_scope = false; return; } - + write_end_block (); write_newline (); } @@ -223,13 +223,49 @@ public class Vala.InterfaceWriter : CodeVisitor { if (internal_scope) { return; } - + write_indent (); write_identifier (ev.name); write_string (","); write_newline (); } + public override void visit_begin_flags (Flags! fl) { + if (fl.access == MemberAccessibility.PRIVATE) { + internal_scope = true; + return; + } + + write_indent (); + write_string ("[CCode (cprefix = \"%s\")]".printf (fl.get_cprefix ())); + + write_indent (); + write_string ("public flags "); + write_identifier (fl.name); + write_begin_block (); + } + + public override void visit_end_flags (Flags! fl) { + if (fl.access == MemberAccessibility.PRIVATE) { + internal_scope = false; + return; + } + + write_end_block (); + write_newline (); + } + + public override void visit_flags_value (FlagsValue! fv) { + if (internal_scope) { + return; + } + + write_indent (); + write_identifier (fv.name); + write_string (","); + write_newline (); + } + public override void visit_constant (Constant! c) { if (internal_scope) { return; diff --git a/vala/vala/valasemanticanalyzer.vala b/vala/vala/valasemanticanalyzer.vala index 547dc87..39e5582 100644 --- a/vala/vala/valasemanticanalyzer.vala +++ b/vala/vala/valasemanticanalyzer.vala @@ -957,7 +957,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } else if (node is VariableDeclarator) { var decl = (VariableDeclarator) node; return decl.type_reference; - } else if (node is EnumValue) { + } else if (node is EnumValue || node is FlagsValue) { var type = new TypeReference (); type.data_type = (DataType) node.symbol.parent_symbol.node; return type; diff --git a/vala/vala/valasymbolbuilder.vala b/vala/vala/valasymbolbuilder.vala index 9336241..33548a1 100644 --- a/vala/vala/valasymbolbuilder.vala +++ b/vala/vala/valasymbolbuilder.vala @@ -134,21 +134,21 @@ public class Vala.SymbolBuilder : CodeVisitor { current_symbol = current_symbol.parent_symbol; } - + public override void visit_begin_enum (Enum! en) { if (add_symbol (en.name, en) == null) { return; } - + current_symbol = en.symbol; } - + public override void visit_end_enum (Enum! en) { if (en.error) { /* skip enums with errors */ return; } - + current_symbol = current_symbol.parent_symbol; } @@ -156,7 +156,29 @@ public class Vala.SymbolBuilder : CodeVisitor { ev.symbol = new Symbol (ev); current_symbol.add (ev.name, ev.symbol); } - + + public override void visit_begin_flags (Flags! fl) { + if (add_symbol (fl.name, fl) == null) { + return; + } + + current_symbol = fl.symbol; + } + + public override void visit_end_flags (Flags! fl) { + if (fl.error) { + /* skip flags with errors */ + return; + } + + current_symbol = current_symbol.parent_symbol; + } + + public override void visit_flags_value (FlagsValue! fv) { + fv.symbol = new Symbol (fv); + current_symbol.add (fv.name, fv.symbol); + } + public override void visit_begin_callback (Callback! cb) { if (add_symbol (cb.name, cb) == null) { return; -- 2.7.4