Commit 612e05c3 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

add basic support for flags, fixes bug 434511

2007-04-30  Jürg Billeter  <j@bitron.ch>

	* 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
parent 9890a3fa
2007-04-30 Jürg Billeter <j@bitron.ch>
* 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 <j@bitron.ch>
* vala/valasemanticanalyzer.vala: check that void return values are not
......
......@@ -332,6 +332,10 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%type <list> enum_member_declarations
%type <enum_value> enum_member_declaration
%type <flags> flags_declaration
%type <list> flags_body
%type <list> opt_flags_member_declarations
%type <list> flags_member_declarations
%type <flags_value> flags_member_declaration
%type <callback> callback_declaration
%type <constant> constant_declaration
%type <field> 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
......
......@@ -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 ();
}
......
......@@ -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 ()) {
......
......@@ -148,5 +148,5 @@ public class Vala.Enum : DataType {
public override string get_default_value () {
return "0";
}
}
}
/* 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<FlagsValue> values;
string cname;
private List<FlagsValue> 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";
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment