+2006-05-21 Jürg Billeter <j@bitron.ch>
+
+ * vala/scanner.l: support file comments, BREAK, CONTINUE
+ * vala/parser.y: support break and continue, add more comments
+ * vala/valacodecontext.vala: find cyclic header dependencies
+ * vala/valasourcefile.vala: add get_namespaces method, add dependency
+ information, add add_symbol_dependency method, add
+ SourceFileDependencyType enum
+ * vala/valasourcefilecycle.vala
+ * vala/valacodevisitor.vala: support break and continue statements
+ * vala/valaparser.vala: support file comments
+ * vala/valasemanticanalyzer.vala: record dependency information
+ * vala/valacodegenerator.vala: add include directives, type forward
+ declarations, once section, enum values, method return types, and more
+ comments
+ * vala/valablock.vala, vala/valadeclarationstatement.vala,
+ vala/valaemptystatement.vala, vala/valaexpressionstatement.vala,
+ vala/valaforeachstatement.vala, vala/valaforstatement.vala,
+ vala/valaifstatement.vala, vala/valareturnstatement.vala,
+ vala/valastatement.vala, vala/valawhilestatement.vala: move
+ source_reference property to Statement class
+ * vala/valaclass.vala, vala/valaenum.vala, vala/valastruct.vala,
+ vala/valatype.vala: move name, source_reference, namespace, and
+ get_cheader_filenames to Type class
+ * vala/valabreakstatement.vala
+ * vala/valacontinuestatement.vala
+ * vala/valaenum.vala: fix cname, add get_upper_case_cname method
+ * vala/valaenumvalue.vala: add get_cname method
+ * vala/valafield.vala: add access field
+ * vala/valanamespace.vala: add get_structs, get_classes, and
+ get_cheader_filenames methods, support cheader_filename attribute
+ * vala/valastruct.vala: support cheader_filename attribute
+ * vala/valatypereference.vala: support void cname
+ * vala/vala.h: update
+ * ccode/valaccodeblock.vala: support comments before statements
+ * ccode/valaccodeenum.vala: optionally use typedef
+ * ccode/valaccodefunction.vala: add copy method
+ * ccode/valaccodenewline.vala
+ * ccode/valaccodeoncesection.vala
+ * ccode/valaccodewriter.vala: use whole line for comments
+ * bindings/glib-2.0.vala: add cheader_filename attributes, extend string
+ types
+ * valac/generator.c: fix private field access, include string.h
+
2006-05-19 Jürg Billeter <j@bitron.ch>
* vala/valacodegenerator.vala: include header file in corresponding
* Jürg Billeter <j@bitron.ch>
*/
-[CCode (cname = "gboolean")]
+[CCode (cname = "gboolean", cheader_filename = "glib.h")]
public struct bool {
}
-[CCode (cname = "gpointer")]
+[CCode (cname = "gpointer", cheader_filename = "glib.h")]
public struct pointer {
}
+[CCode (cheader_filename = "glib.h")]
public struct char {
}
-[CCode (cname = "unsigned char")]
+[CCode (cname = "unsigned char", cheader_filename = "glib.h")]
public struct uchar {
}
+[CCode (cheader_filename = "glib.h")]
public struct int {
}
-[CCode (cname = "unsigned int")]
+[CCode (cname = "unsigned int", cheader_filename = "glib.h")]
public struct uint {
}
+[CCode (cheader_filename = "glib.h")]
public struct short {
}
-[CCode (cname = "unsigned short")]
+[CCode (cname = "unsigned short", cheader_filename = "glib.h")]
public struct ushort {
}
+[CCode (cheader_filename = "glib.h")]
public struct long {
}
-[CCode (cname = "unsigned long")]
+[CCode (cname = "unsigned long", cheader_filename = "glib.h")]
public struct ulong {
}
-[CCode (cname = "gint8")]
+[CCode (cname = "gint8", cheader_filename = "glib.h")]
public struct int8 {
}
-[CCode (cname = "guint8")]
+[CCode (cname = "guint8", cheader_filename = "glib.h")]
public struct uint8 {
}
-[CCode (cname = "gint16")]
+[CCode (cname = "gint16", cheader_filename = "glib.h")]
public struct int16 {
}
-[CCode (cname = "guint16")]
+[CCode (cname = "guint16", cheader_filename = "glib.h")]
public struct uint16 {
}
-[CCode (cname = "gint32")]
+[CCode (cname = "gint32", cheader_filename = "glib.h")]
public struct int32 {
}
-[CCode (cname = "guint32")]
+[CCode (cname = "guint32", cheader_filename = "glib.h")]
public struct uint32 {
}
-[CCode (cname = "gint64")]
+[CCode (cname = "gint64", cheader_filename = "glib.h")]
public struct int64 {
}
-[CCode (cname = "guint64")]
+[CCode (cname = "guint64", cheader_filename = "glib.h")]
public struct uint64 {
}
-[CCode (cname = "gunichar")]
+[CCode (cname = "gunichar", cheader_filename = "glib.h")]
public struct unichar {
+ [CCode (cname = "g_unichar_isalnum")]
+ public bool isalnum ();
[CCode (cname = "g_unichar_isupper")]
public bool isupper ();
+ [CCode (cname = "g_unichar_toupper")]
+ public unichar toupper ();
[CCode (cname = "g_unichar_tolower")]
public unichar tolower ();
}
[ReferenceType ()]
[AllowPointerArithmetic ()]
-[CCode (cname = "char")]
+[CCode (cname = "char", cheader_filename = "string.h,glib.h")]
public struct astring {
[CCode (cname = "g_str_has_suffix")]
public bool has_suffix (string suffix);
}
[ReferenceType ()]
-[CCode (cname = "char")]
+[CCode (cname = "char", cheader_filename = "string.h,glib.h")]
public struct string {
[CCode (cname = "g_str_has_suffix")]
public bool has_suffix (string suffix);
public ref string ndup (int n);
[CCode (cname = "g_strcompress")]
public ref string compress ();
+ [CCode (cname = "g_strsplit")]
+ public ref string[] split (string delimiter, int max_tokens /* = 0 */);
+
[CCode (cname = "g_utf8_next_char")]
public string next_char ();
[CCode (cname = "g_utf8_get_char")]
[CCode (cname = "g_utf8_offset_to_pointer")]
[PlusOperator ()]
public string offset (long offset);
+ [CCode (cname = "g_utf8_pointer_to_offset")]
+ public long pointer_to_offset (string pos);
[CCode (cname = "g_utf8_prev_char")]
public string prev_char ();
[CCode (cname = "g_utf8_strlen")]
public long len (long max /*= -1*/);
+ [CCode (cname = "g_utf8_strchr")]
+ public string chr (long len, unichar c);
[CCode (cname = "g_utf8_strup")]
public ref string up (long len /*= -1*/);
}
[Import ()]
-[CCode (cprefix = "G", lower_case_cprefix = "g_", include_filename = "glib.h")]
+[CCode (cprefix = "G", lower_case_cprefix = "g_", cheader_filename = "glib.h")]
namespace GLib {
public struct Path {
public static ref string get_basename (string file_name);
public struct ObjectConstructParam {
}
- public class Object {
+ [CCode (cheader_filename = "glib-object.h")]
+ public abstract class Object {
public virtual Object constructor (Type type, uint n_construct_properties, ObjectConstructParam[] construct_properties);
}
public struct Error {
}
+ public static void return_if_fail (bool expr);
+
[ReferenceType ()]
- [CCode (cname = "FILE")]
+ [CCode (cname = "FILE", cheader_filename = "stdio.h")]
public struct File {
[CCode (cname = "fopen")]
public static ref File open (string path, string mode);
public void close ();
}
- [CCode (cname = "stderr")]
+ [CCode (cname = "stderr", cheader_filename = "stdio.h")]
public static GLib.File stderr;
[Unknown (reference_type = true)]
public pointer nth_data (uint n);
public List<G> nth_prev (uint n);
+ public List<G> find_custom (G data, CompareFunc func);
+
public List<G> find (G data);
public int position (List<G> llink);
public int index (G data);
public List<G> prev;
}
+ public struct CompareFunc {
+ }
+
+ [CCode (cname = "strcmp")]
+ public static GLib.CompareFunc strcmp;
+
[ReferenceType ()]
public struct HashTable<K,V> {
public static ref HashTable new (HashFunc hash_func, EqualFunc key_equal_func);
[ReferenceType ()]
public struct String {
public static ref String new (string init);
- public void append_c (char c);
- public void append_unichar (unichar wc);
+ public String append (string val);
+ public String append_c (char c);
+ public String append_unichar (unichar wc);
+ public String erase (long pos, long len);
public string str;
public long len;
namespace Vala {
public class CCodeBlock : CCodeStatement {
- ref List<ref CCodeStatement> statements;
+ List<CCodeNode> statements;
- public void add_statement (string statement) {
+ public void add_statement (CCodeNode statement) {
+ /* allow generic nodes to include comments */
statements.append (statement);
}
public override void write (CCodeWriter writer) {
writer.write_begin_block ();
- foreach (CCodeStatement statement in statements) {
+ foreach (CCodeNode statement in statements) {
if (statement != null) {
statement.write (writer);
}
List<string> values;
public void add_value (string name, string value) {
- values.append ("%s = %s".printf (name, value));
+ if (value == null) {
+ values.append (name);
+ } else {
+ values.append ("%s = %s".printf (name, value));
+ }
}
public override void write (CCodeWriter writer) {
+ if (name != null) {
+ writer.write_string ("typedef ");
+ }
writer.write_string ("enum ");
- writer.write_string (name);
writer.write_begin_block ();
foreach (string value in values) {
writer.write_indent ();
writer.write_string (value);
- writer.write_string (",\n");
+ writer.write_string (",");
+ writer.write_newline ();
}
writer.write_end_block ();
- writer.write_string (";\n");
+ if (name != null) {
+ writer.write_string (" ");
+ writer.write_string (name);
+ }
+ writer.write_string (";");
+ writer.write_newline ();
}
}
}
parameters.append (param);
}
+ public ref CCodeFunction copy () {
+ var func = new CCodeFunction (name = name, return_type = return_type);
+ func.modifiers = modifiers;
+ func.parameters = parameters.copy ();
+ func.block = block;
+ return func;
+ }
+
public override void write (CCodeWriter writer) {
- writer.write_newline ();
+ writer.write_indent ();
if ((modifiers & CCodeModifiers.STATIC) == CCodeModifiers.STATIC) {
writer.write_string ("static ");
}
} else {
writer.write_newline ();
block.write (writer);
+ writer.write_newline ();
}
writer.write_newline ();
}
--- /dev/null
+/* valaccodenewline.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;
+
+namespace Vala {
+ public class CCodeNewline : CCodeNode {
+ public override void write (CCodeWriter writer) {
+ writer.write_newline ();
+ }
+ }
+}
--- /dev/null
+/* valaccodeoncesection.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;
+
+namespace Vala {
+ public class CCodeOnceSection : CCodeFragment {
+ public string define { get; construct; }
+
+ public override void write (CCodeWriter writer) {
+ writer.write_indent ();
+ writer.write_string ("#ifndef ");
+ writer.write_string (define);
+ writer.write_newline ();
+ writer.write_string ("#define ");
+ writer.write_string (define);
+ writer.write_newline ();
+ foreach (CCodeNode node in children) {
+ node.write (writer);
+ }
+ writer.write_indent ();
+ writer.write_string ("#endif");
+ writer.write_newline ();
+ }
+ }
+}
}
public void write_comment (string text) {
+ write_indent ();
stream.printf ("/*%s*/", text);
+ write_newline ();
}
}
}
%token PERCENT "%"
%token ABSTRACT "abstract"
+%token BREAK "break"
%token CLASS "class"
%token CONST "const"
%token CONSTRUCT "construct"
+%token CONTINUE "continue"
%token ELSE "else"
%token ENUM "enum"
%token VALA_FALSE "false"
%type <list> statement_expression_list
%type <statement> foreach_statement
%type <statement> jump_statement
+%type <statement> break_statement
+%type <statement> continue_statement
%type <statement> return_statement
%type <namespace> namespace_declaration
%type <class> class_declaration
;
compilation_unit
- : comment opt_using_directives opt_outer_declarations
- {
- current_source_file->comment = $1;
- }
+ : opt_using_directives opt_outer_declarations
;
type_name
expression
: conditional_expression
+ | assignment
;
statement
;
declaration_statement
- : local_variable_declaration
+ : comment local_variable_declaration
{
- $$ = VALA_STATEMENT (vala_declaration_statement_new ($1, src(@1)));
+ $$ = VALA_STATEMENT (vala_declaration_statement_new ($2, src_com(@2, $1)));
}
;
;
expression_statement
- : statement_expression SEMICOLON
+ : comment statement_expression SEMICOLON
{
- $$ = VALA_STATEMENT (vala_expression_statement_new ($1, src(@1)));
+ $$ = VALA_STATEMENT (vala_expression_statement_new ($2, src_com(@2, $1)));
}
;
;
jump_statement
- : return_statement
+ : break_statement
+ | continue_statement
+ | return_statement
+ ;
+
+break_statement
+ : BREAK SEMICOLON
+ {
+ $$ = VALA_STATEMENT (vala_break_statement_new (src(@1)));
+ }
+ ;
+
+continue_statement
+ : CONTINUE SEMICOLON
+ {
+ $$ = VALA_STATEMENT (vala_continue_statement_new (src(@1)));
+ }
;
return_statement
{
GList *l;
current_struct = VALA_STRUCT (vala_class_new ($6, src_com (@6, $1)));
+ VALA_CODE_NODE(current_struct)->attributes = $2;
for (l = $7; l != NULL; l = l->next) {
vala_struct_add_type_parameter (current_struct, l->data);
}
}
class_body
{
- $$ = current_struct;
+ $$ = VALA_CLASS (current_struct);
current_struct = NULL;
}
;
: comment opt_attributes opt_access_modifier opt_modifiers opt_ref type variable_declarator SEMICOLON
{
$$ = vala_field_new (vala_variable_declarator_get_name ($7), $6, vala_variable_declarator_get_initializer ($7), src_com (@6, $1));
+ if ($3 != 0) {
+ $$->access = $3;
+ }
}
;
#define YY_DECL int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param, ValaParser *parser)
#define uploc { yylloc->first_column = yylloc->last_column + 1; yylloc->last_column += strlen (yytext); }
+
+static gboolean file_comment = FALSE;
%}
%option yylineno
%%
-"/*" { uploc; BEGIN (IN_COMMENT); }
-<IN_COMMENT>[^*\n]* { uploc; yymore (); }
-<IN_COMMENT>"*"+[^*/\n]* { uploc; yymore (); }
+"/*" { uploc; file_comment = (yylineno == 1); BEGIN (IN_COMMENT); }
+<IN_COMMENT>"*/" { uploc; BEGIN (INITIAL); yytext[strlen (yytext) - 2] = '\0'; vala_parser_push_comment (parser, g_strdup (yytext), file_comment); }
+<IN_COMMENT>[^*\n]+ { uploc; yymore (); }
+<IN_COMMENT>"*" { uploc; yymore (); }
<IN_COMMENT>\n { yylloc->first_line = yylloc->last_line = yylineno; yylloc->first_column = 1; yylloc->last_column = 0; yymore (); }
-<IN_COMMENT>"*/" { uploc; BEGIN (INITIAL); yytext[strlen (yytext) - 2] = '\0'; vala_parser_push_comment (parser, g_strdup (yytext)); }
-"//".* { uploc; vala_parser_push_comment (parser, g_strdup (yytext + 2)); }
+"//".* { uploc; vala_parser_push_comment (parser, g_strdup (yytext + 2), FALSE); }
"{" { uploc; return OPEN_BRACE; }
"}" { uploc; return CLOSE_BRACE; }
"@"[[:alnum:]_]+ { uploc; yylval->str = strdup (yytext + 1); return IDENTIFIER; }
"abstract" { uploc; return ABSTRACT; }
+"break" { uploc; return BREAK; }
"class" { uploc; return CLASS; }
"const" { uploc; return CONST; }
"construct" { uploc; return CONSTRUCT; }
+"continue" { uploc; return CONTINUE; }
"else" { uploc; return ELSE; }
"enum" { uploc; return ENUM; }
"false" { uploc; return VALA_FALSE; }
#include <vala/valabinaryexpression.h>
#include <vala/valablock.h>
#include <vala/valabooleanliteral.h>
+#include <vala/valabreakstatement.h>
#include <vala/valacastexpression.h>
#include <vala/valacharacterliteral.h>
#include <vala/valaclass.h>
#include <vala/valacodecontext.h>
#include <vala/valaconditionalexpression.h>
#include <vala/valaconstant.h>
+#include <vala/valacontinuestatement.h>
#include <vala/valadeclarationstatement.h>
#include <vala/valaemptystatement.h>
#include <vala/valaenum.h>
namespace Vala {
public class Block : Statement {
public List<Statement> statement_list { get; construct; }
- public SourceReference source_reference { get; construct; }
public static ref Block new (List<Statement> statement_list, SourceReference source) {
return (new Block (statement_list = statement_list, source_reference = source));
--- /dev/null
+/* valabreakstatement.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;
+
+namespace Vala {
+ public class BreakStatement : Statement {
+ public static ref BreakStatement new (SourceReference source) {
+ return (new BreakStatement (source_reference = source));
+ }
+
+ public override void accept (CodeVisitor visitor) {
+ visitor.visit_break_statement (this);
+ }
+ }
+}
namespace Vala {
public class Class : Struct {
- public SourceReference source_reference { get; construct; }
public List<TypeReference> base_types;
public Class base_class;
List<SourceFile> source_files;
public Symbol root = new Symbol ();
+ List<SourceFileCycle> cycles;
+
public ref List<SourceFile> get_source_files () {
return source_files.copy ();
}
file.accept (visitor);
}
}
+
+ public void find_header_cycles () {
+ /* find cycles in dependencies between source files */
+ foreach (SourceFile file in source_files) {
+ /* we're only interested in internal source files */
+ if (!file.pkg) {
+ if (file.mark == 0) {
+ visit (file, null);
+ }
+ }
+ }
+
+ /* find one head for each cycle, it must not have any
+ * hard dependencies on other files in the cycle
+ */
+ foreach (SourceFileCycle cycle in cycles) {
+ cycle.head = find_cycle_head ((SourceFile) cycle.files.data);
+ cycle.head.is_cycle_head = true;
+ }
+
+ /* connect the source files in a non-cyclic way
+ * cycle members connect to the head of their cycle
+ */
+ foreach (SourceFile file2 in source_files) {
+ /* we're only interested in internal source files */
+ if (!file2.pkg) {
+ foreach (SourceFile dep in file2.header_internal_dependencies) {
+ if (file2.cycle != null && dep.cycle == file2.cycle) {
+ /* in the same cycle */
+ if (!file2.is_cycle_head) {
+ /* include header of cycle head */
+ file2.header_internal_includes.append (file2.cycle.head.get_cheader_filename ());
+ }
+ } else {
+ /* we can just include the headers if they are not in a cycle or not in the same cycle as the current file */
+ file2.header_internal_includes.append (dep.get_cheader_filename ());
+ }
+ }
+ }
+ }
+
+ }
+
+ private SourceFile find_cycle_head (SourceFile file) {
+ foreach (SourceFile dep in file.header_internal_full_dependencies) {
+ foreach (SourceFile cycle_file in file.cycle.files) {
+ if (dep == cycle_file) {
+ return find_cycle_head (dep);
+ }
+ }
+ }
+ /* no hard dependencies on members of the same cycle found
+ * source file suitable as cycle head
+ */
+ return file;
+ }
+
+ private void visit (SourceFile file, List<SourceFile> chain) {
+ var l = chain.copy ();
+ l.append (file);
+
+ /* mark file as currently being visited */
+ file.mark = 1;
+
+ foreach (SourceFile dep in file.header_internal_dependencies) {
+ if (file != dep) {
+ if (dep.mark == 1) {
+ /* found cycle */
+
+ var cycle = new SourceFileCycle ();
+ cycles.append (cycle);
+
+ bool cycle_start_found = false;
+ foreach (SourceFile cycle_file in l) {
+ if (!cycle_start_found) {
+ if (cycle_file == dep) {
+ cycle_start_found = true;
+ }
+ }
+ if (cycle_start_found) {
+ if (cycle_file.cycle != null) {
+ /* file already in a cycle */
+ if (cycle_file.cycle != cycle) {
+ /* file is in an other cycle, merge the two cycles */
+
+ cycles.remove (cycle_file.cycle);
+
+ foreach (SourceFile inner_cycle_file in cycle_file.cycle.files) {
+ if (inner_cycle_file.cycle != cycle) {
+ /* file in inner cycle not yet added to outer cycle */
+ cycle.files.append (inner_cycle_file);
+ inner_cycle_file.cycle = cycle;
+ }
+ }
+ }
+ } else {
+ cycle.files.append (cycle_file);
+ cycle_file.cycle = cycle;
+ }
+ }
+ }
+ } else if (dep.mark == 0) {
+ /* found not yet visited file */
+
+ visit (dep, l);
+ }
+ }
+ }
+
+ /* mark file as successfully visited */
+ file.mark = 2;
+ }
}
}
CCodeStruct instance_struct;
CCodeStruct class_struct;
+ CCodeEnum cenum;
CCodeFunction function;
CCodeBlock block;
TypeReference reference; // dummy for dependency resolution
Symbol dummy_symbol; // dummy for dependency resolution
+ SourceFileCycle dummy_cycle; // dummy for dependency resolution
public void emit (CodeContext context) {
+ context.find_header_cycles ();
+
/* we're only interested in non-pkg source files */
foreach (SourceFile file in context.get_source_files ()) {
if (!file.pkg) {
source_type_member_declaration = new CCodeFragment ();
source_type_member_definition = new CCodeFragment ();
- if (source_file.comment != null) {
- header_begin.append (new CCodeComment (text = source_file.comment));
+ source_include_directives.append (new CCodeIncludeDirective (filename = source_file.get_cheader_filename ()));
+
+ List<string> used_includes = null;
+ used_includes.append (source_file.get_cheader_filename ());
+
+ foreach (string filename1 in source_file.header_external_includes) {
+ if (used_includes.find_custom (filename1, strcmp) == null) {
+ header_begin.append (new CCodeIncludeDirective (filename = filename1));
+ used_includes.append (filename1);
+ }
}
+ foreach (string filename2 in source_file.header_internal_includes) {
+ if (used_includes.find_custom (filename2, strcmp) == null) {
+ header_begin.append (new CCodeIncludeDirective (filename = filename2));
+ used_includes.append (filename2);
+ }
+ }
+ foreach (string filename3 in source_file.source_includes) {
+ if (used_includes.find_custom (filename3, strcmp) == null) {
+ source_include_directives.append (new CCodeIncludeDirective (filename = filename3));
+ used_includes.append (filename3);
+ }
+ }
+ if (source_file.is_cycle_head) {
+ foreach (SourceFile cycle_file in source_file.cycle.files) {
+ foreach (Namespace ns in cycle_file.get_namespaces ()) {
+ foreach (Struct st in ns.get_structs ()) {
+ header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (st.get_cname ()), typedef_name = st.get_cname ()));
+ }
+ foreach (Class cl in ns.get_classes ()) {
+ header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (cl.get_cname ()), typedef_name = cl.get_cname ()));
+ header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%sClass".printf (cl.get_cname ()), typedef_name = "%sClass".printf (cl.get_cname ())));
+ }
+ }
+ }
+ }
+ }
+
+ private static ref string get_define_for_filename (string filename) {
+ var define = String.new ("__");
- source_include_directives.append (new CCodeIncludeDirective (filename = source_file.get_cheader_filename ()));
+ var i = filename;
+ while (i.len (-1) > 0) {
+ var c = i.get_char ();
+ if (c.isalnum () && c < 128) {
+ define.append_unichar (c.toupper ());
+ } else {
+ define.append_c ('_');
+ }
+
+ i = i.next_char ();
+ }
+
+ define.append ("__");
+
+ return define.str;
}
public override void visit_end_source_file (SourceFile source_file) {
+ var header_define = get_define_for_filename (source_file.get_cheader_filename ());
+
+ CCodeComment comment = null;
+ if (source_file.comment != null) {
+ comment = new CCodeComment (text = source_file.comment);
+ }
+
var writer = new CCodeWriter (stream = File.open (source_file.get_cheader_filename (), "w"));
- header_begin.write (writer);
- header_type_declaration.write (writer);
- header_type_definition.write (writer);
- header_type_member_declaration.write (writer);
+ if (comment != null) {
+ comment.write (writer);
+ }
+ writer.write_newline ();
+ var once = new CCodeOnceSection (define = header_define);
+ once.append (new CCodeNewline ());
+ once.append (header_begin);
+ once.append (new CCodeNewline ());
+ once.append (new CCodeIdentifier (name = "G_BEGIN_DECLS"));
+ once.append (new CCodeNewline ());
+ once.append (new CCodeNewline ());
+ once.append (header_type_declaration);
+ once.append (new CCodeNewline ());
+ once.append (header_type_definition);
+ once.append (new CCodeNewline ());
+ once.append (header_type_member_declaration);
+ once.append (new CCodeNewline ());
+ once.append (new CCodeIdentifier (name = "G_END_DECLS"));
+ once.append (new CCodeNewline ());
+ once.append (new CCodeNewline ());
+ once.write (writer);
writer.close ();
writer = new CCodeWriter (stream = File.open (source_file.get_csource_filename (), "w"));
+ if (comment != null) {
+ comment.write (writer);
+ }
source_begin.write (writer);
+ writer.write_newline ();
source_include_directives.write (writer);
+ writer.write_newline ();
source_type_member_declaration.write (writer);
+ writer.write_newline ();
source_type_member_definition.write (writer);
+ writer.write_newline ();
writer.close ();
header_begin = null;
class_struct = new CCodeStruct (name = "_%sClass".printf (cl.get_cname ()));
+ header_type_declaration.append (new CCodeNewline ());
var macro = "(%s_get_type ())".printf (cl.get_lower_case_cname (null));
header_type_declaration.append (new CCodeMacroReplacement (name = cl.get_upper_case_cname ("TYPE_"), replacement = macro));
macro = "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
header_type_declaration.append (new CCodeMacroReplacement (name = "%s_GET_CLASS(obj)".printf (cl.get_upper_case_cname (null)), replacement = macro));
+ header_type_declaration.append (new CCodeNewline ());
-
- header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (instance_struct.name), typedef_name = cl.get_cname ()));
- header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (class_struct.name), typedef_name = "%sClass".printf (cl.get_cname ())));
+
+ if (cl.source_reference.file.cycle == null) {
+ header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (instance_struct.name), typedef_name = cl.get_cname ()));
+ header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (class_struct.name), typedef_name = "%sClass".printf (cl.get_cname ())));
+ }
instance_struct.add_field (cl.base_class.get_cname (), "parent");
class_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent");
}
public override void visit_begin_enum (Enum en) {
- instance_struct = new CCodeEnum (name = "_%s".printf (en.name));
+ cenum = new CCodeEnum (name = en.get_cname ());
if (en.source_reference.comment != null) {
header_type_definition.append (new CCodeComment (text = en.source_reference.comment));
}
- header_type_definition.append (instance_struct);
+ header_type_definition.append (cenum);
+ }
+
+ public override void visit_enum_value (EnumValue ev) {
+ cenum.add_value (ev.get_cname (), null);
}
public override void visit_field (Field f) {
- instance_struct.add_field (f.type_reference.get_cname (), f.name);
+ if (f.access == MemberAccessibility.PUBLIC) {
+ instance_struct.add_field (f.type_reference.get_cname (), f.name);
+ }
}
public override void visit_end_method (Method m) {
- var cmethod_decl = new CCodeFunction (name = m.get_cname (), return_type = "void");
- function = new CCodeFunction (name = m.get_cname (), return_type = "void");
-
- if (m.access == MemberAccessibility.PUBLIC) {
- header_type_member_declaration.append (cmethod_decl);
- } else {
- cmethod_decl.modifiers |= CCodeModifiers.STATIC;
- function.modifiers |= CCodeModifiers.STATIC;
- source_type_member_declaration.append (cmethod_decl);
- }
+ function = new CCodeFunction (name = m.get_cname (), return_type = m.return_type.get_cname ());
if (m.instance) {
var st = (Struct) m.symbol.parent_symbol.node;
var this_type = new TypeReference ();
this_type.type = st;
var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
- cmethod_decl.add_parameter (cparam);
function.add_parameter (cparam);
}
foreach (FormalParameter param in m.get_parameters ()) {
- cmethod_decl.add_parameter ((CCodeFormalParameter) param.ccodenode);
function.add_parameter ((CCodeFormalParameter) param.ccodenode);
}
+
+ if (m.access == MemberAccessibility.PUBLIC) {
+ header_type_member_declaration.append (function.copy ());
+ } else {
+ function.modifiers |= CCodeModifiers.STATIC;
+ source_type_member_declaration.append (function.copy ());
+ }
if (m.body != null) {
function.block = m.body.ccodenode;
var cblock = new CCodeBlock ();
foreach (Statement stmt in b.statement_list) {
+ var src = stmt.source_reference;
+ if (src != null && src.comment != null) {
+ cblock.add_statement (new CCodeComment (text = src.comment));
+ }
+
if (stmt.ccodenode is CCodeFragment) {
foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).children) {
cblock.add_statement (cstmt);
public virtual void visit_end_foreach_statement (ForeachStatement stmt) {
}
+ public virtual void visit_break_statement (BreakStatement stmt) {
+ }
+
+ public virtual void visit_continue_statement (ContinueStatement stmt) {
+ }
+
public virtual void visit_return_statement (ReturnStatement stmt) {
}
--- /dev/null
+/* valacontinuestatement.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;
+
+namespace Vala {
+ public class ContinueStatement : Statement {
+ public static ref ContinueStatement new (SourceReference source) {
+ return (new ContinueStatement (source_reference = source));
+ }
+
+ public override void accept (CodeVisitor visitor) {
+ visitor.visit_continue_statement (this);
+ }
+ }
+}
namespace Vala {
public class DeclarationStatement : Statement {
public LocalVariableDeclaration declaration { get; construct; }
- public SourceReference source_reference { get; construct; }
public static ref DeclarationStatement new (LocalVariableDeclaration decl, SourceReference source) {
return (new DeclarationStatement (declaration = decl, source_reference = source));
namespace Vala {
public class EmptyStatement : Statement {
- public SourceReference source_reference { get; construct; }
-
public static ref EmptyStatement new (SourceReference source) {
return (new EmptyStatement (source_reference = source));
}
namespace Vala {
public class Enum : Type_ {
- public string name { get; construct; }
- public SourceReference source_reference { get; construct; }
- public Namespace @namespace;
List<EnumValue> values;
public static ref Enum new (string name, SourceReference source) {
visitor.visit_end_enum (this);
}
-
+
+ string cname;
public override string get_cname () {
- return name;
+ if (cname == null) {
+ cname = "%s%s".printf (@namespace.get_cprefix (), name);
+ }
+ return cname;
+ }
+
+ public string get_upper_case_cname () {
+ return "%s%s".printf (@namespace.get_lower_case_cprefix (), Namespace.camel_case_to_lower_case (name)).up (-1);
}
public override bool is_reference_type () {
public string name { get; construct; }
public IntegerLiteral value { get; construct; }
public SourceReference source_reference { get; construct; }
+
+ Symbol dummy_symbol; // dummy symbol for broken dependency handling
public static ref EnumValue new (string name) {
return (new EnumValue (name = name));
public override void accept (CodeVisitor visitor) {
visitor.visit_enum_value (this);
}
+
+ string cname;
+ public string get_cname () {
+ if (cname == null) {
+ var en = (Enum) symbol.parent_symbol.node;
+ cname = "%s_%s".printf (en.get_upper_case_cname (), name);
+ }
+ return cname;
+ }
}
}
namespace Vala {
public class ExpressionStatement : Statement {
public Expression expression { get; construct; }
- public SourceReference source_reference { get; construct; }
public static ref ExpressionStatement new (Expression expr, SourceReference source) {
return (new ExpressionStatement (expression = expr, source_reference = source));
public string name { get; construct; }
public TypeReference type_reference { get; construct; }
public Expression initializer { get; construct; }
+ public MemberAccessibility access;
public SourceReference source_reference { get; construct; }
public static ref Field new (string name, TypeReference type, Expression init, SourceReference source) {
public string variable_name { get; construct; }
public Expression collection { get; construct; }
public Statement body { get; construct; }
- public SourceReference source_reference { get; construct; }
public static ref ForeachStatement new (TypeReference type, string id, Expression col, Statement body, SourceReference source) {
return (new ForeachStatement (type_reference = type, variable_name = id, collection = col, body = body, source_reference = source));
public Expression condition { get; construct; }
public List<Expression> iterator { get; construct; }
public Statement body { get; construct; }
- public SourceReference source_reference { get; construct; }
public static ref ForStatement new (List<StatementExpression> init, Expression cond, List<StatementExpression> iter, Statement body, SourceReference source) {
return (new ForStatement (initializer = init, condition = cond, iterator = iter, body = body, source_reference = source));
public Expression condition { get; construct; }
public Statement true_statement { get; construct; }
public Statement false_statement { get; construct; }
- public SourceReference source_reference { get; construct; }
public static ref IfStatement new (Expression cond, Statement true_stmt, Statement false_stmt, SourceReference source) {
return (new IfStatement (condition = cond, true_statement = true_stmt, false_statement = false_stmt, source_reference = source));
en.@namespace = this;
}
+ public ref List<Struct> get_structs () {
+ return structs.copy ();
+ }
+
public ref List<Class> get_classes () {
return classes.copy ();
}
this.lower_case_cprefix = cprefix;
}
+ List<string> cheader_filenames;
+
+ public ref List<string> get_cheader_filenames () {
+ if (cheader_filenames == null) {
+ cheader_filenames.append (source_reference.file.get_cheader_filename ());
+ }
+ return cheader_filenames.copy ();
+ }
+
void process_ccode_attribute (Attribute a) {
foreach (NamedArgument arg in a.args) {
if (arg.name.collate ("cprefix") == 0) {
set_lower_case_cprefix (((StringLiteral) lit).eval ());
}
}
+ } else if (arg.name.collate ("cheader_filename") == 0) {
+ /* 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)) {
+ cheader_filenames.append (filename);
+ }
+ }
+ }
}
}
}
namespace Vala {
public class Parser : CodeVisitor {
string comment;
+ string _file_comment;
public void parse (CodeContext context) {
context.accept (this);
public override void visit_begin_source_file (SourceFile source_file) {
parse_file (source_file);
+ source_file.comment = _file_comment;
}
- public void push_comment (string comment_item) {
+ public void push_comment (string comment_item, bool file_comment) {
if (comment == null) {
comment = comment_item;
} else {
comment = "%s\n%s".printf (comment, comment_item);
}
+ if (file_comment) {
+ _file_comment = comment;
+ comment = null;
+ }
}
public ref string pop_comment () {
- ref string result = comment;
+ if (comment == null) {
+ return null;
+ }
+
+ String result = String.new (comment);
comment = null;
- return result;
+
+ string index;
+ while ((index = result.str.chr (-1, '\t')) != null) {
+ result.erase (result.str.pointer_to_offset (index), 1);
+ }
+
+ return result.str;
}
[Import ()]
namespace Vala {
public class ReturnStatement : Statement {
public Expression return_expression { get; construct; }
- public SourceReference source_reference { get; construct; }
public static ref ReturnStatement new (Expression result, SourceReference source) {
return (new ReturnStatement (return_expression = result, source_reference = source));
public class SemanticAnalyzer : CodeVisitor {
Symbol root_symbol;
Symbol current_symbol;
+ SourceFile current_source_file;
List<NamespaceReference> current_using_directives;
TypeReference dummy; // required for broken dependency handlind
}
public override void visit_begin_source_file (SourceFile file) {
+ current_source_file = file;
current_using_directives = file.get_using_directives ();
}
public override void visit_begin_class (Class cl) {
current_symbol = cl.symbol;
+
+ if (cl.base_class != null) {
+ current_source_file.add_symbol_dependency (cl.base_class.symbol, SourceFileDependencyType.HEADER_FULL);
+ }
}
public override void visit_end_class (Class cl) {
current_symbol = current_symbol.parent_symbol;
}
+ public override void visit_field (Field f) {
+ if (f.access == MemberAccessibility.PUBLIC) {
+ if (f.type_reference.type != null) {
+ /* is null if it references a type parameter */
+ current_source_file.add_symbol_dependency (f.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+ }
+ } else {
+ if (f.type_reference.type != null) {
+ /* is null if it references a type parameter */
+ current_source_file.add_symbol_dependency (f.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ }
+ }
+ }
+
public override void visit_begin_method (Method m) {
current_symbol = m.symbol;
+
+ if (m.return_type.type != null) {
+ /* is null if it is void or a reference to a type parameter */
+ current_source_file.add_symbol_dependency (m.return_type.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+ }
}
public override void visit_end_method (Method m) {
current_symbol = current_symbol.parent_symbol;
}
+ public override void visit_formal_parameter (FormalParameter p) {
+ if (p.type_reference.type != null) {
+ /* is null if it references a type parameter */
+ current_source_file.add_symbol_dependency (p.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+ }
+ }
+
public override void visit_named_argument (NamedArgument n) {
}
/* var type */
decl.type_reference = decl.initializer.static_type;
}
+
+ if (decl.type_reference.type != null) {
+ current_source_file.add_symbol_dependency (decl.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ }
decl.symbol = new Symbol (node = decl);
current_symbol.add (decl.name, decl.symbol);
}
public override void visit_begin_foreach_statement (ForeachStatement stmt) {
+ if (stmt.type_reference.type != null) {
+ current_source_file.add_symbol_dependency (stmt.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ }
+
stmt.symbol = new Symbol (node = stmt.type_reference);
current_symbol.add (stmt.variable_name, stmt.symbol);
}
stderr.printf ("symbol ´%s´ not found\n", expr.name);
}
+ current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE);
+
expr.static_type = get_static_type_for_node (expr.symbol_reference.node);
}
stderr.printf ("%s: member ´%s´ not found\n", expr.source_reference.to_string (), expr.member_name);
}
+ current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE);
+
expr.static_type = get_static_type_for_node (expr.symbol_reference.node);
}
}
public override void visit_object_creation_expression (ObjectCreationExpression expr) {
+ current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+
expr.static_type = expr.type_reference;
}
public override void visit_cast_expression (CastExpression expr) {
+ current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+
expr.static_type = expr.type_reference;
}
}
List<NamespaceReference> using_directives;
- Namespace global_namespace = new Namespace ();
+ Namespace global_namespace;
List<Namespace> namespaces;
+ private void init () {
+ global_namespace = new Namespace (source_reference = new SourceReference (file = this));
+ }
+
public void add_using_directive (NamespaceReference ns) {
using_directives.append (ns);
}
return global_namespace;
}
+ public ref List<Namespace> get_namespaces () {
+ return namespaces.copy ();
+ }
+
public void accept (CodeVisitor visitor) {
visitor.visit_begin_source_file (this);
visitor.visit_end_source_file (this);
}
- public ref string get_cheader_filename () {
- var basename = filename.ndup (filename.len (-1) - ".vala".len (-1));
- return "%s.h".printf (basename);
+ string cheader_filename = null;
+
+ public string get_cheader_filename () {
+ if (cheader_filename == null) {
+ var basename = filename.ndup (filename.len (-1) - ".vala".len (-1));
+ cheader_filename = "%s.h".printf (basename);
+ }
+ return cheader_filename;
}
- public ref string get_csource_filename () {
- var basename = filename.ndup (filename.len (-1) - ".vala".len (-1));
- return "%s.c".printf (basename);
+ string csource_filename = null;
+
+ public string get_csource_filename () {
+ if (csource_filename == null) {
+ var basename = filename.ndup (filename.len (-1) - ".vala".len (-1));
+ csource_filename = "%s.c".printf (basename);
+ }
+ return csource_filename;
+ }
+
+ public List<string> header_external_includes;
+ public List<string> header_internal_includes;
+ public List<string> source_includes;
+
+ public List<SourceFile> header_internal_full_dependencies;
+ public List<SourceFile> header_internal_dependencies;
+ public SourceFileCycle cycle; // null = not in a cycle; if not null, don't write typedefs
+ public bool is_cycle_head; // if true, write typedefs for all types in the cycle
+ public int mark; // used for cycle detection, 0 = white (not yet visited), 1 = gray (currently visiting), 2 = black (already visited)
+
+ public void add_symbol_dependency (Symbol sym, SourceFileDependencyType dep_type) {
+ Type_ t;
+
+ if (sym.node is Type_) {
+ t = (Type_) sym.node;
+ } else if (sym.node is Method) {
+ if (sym.parent_symbol.node is Type_) {
+ t = (Type_) sym.parent_symbol.node;
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+
+ if (dep_type == SourceFileDependencyType.SOURCE) {
+ source_includes.concat (t.get_cheader_filenames ());
+ return;
+ }
+
+ if (t.source_reference.file.pkg) {
+ /* external package */
+ header_external_includes.concat (t.get_cheader_filenames ());
+ return;
+ }
+
+ if (dep_type == SourceFileDependencyType.HEADER_FULL || !t.is_reference_type ()) {
+ header_internal_includes.concat (t.get_cheader_filenames ());
+ header_internal_full_dependencies.append (t.source_reference.file);
+ }
+
+ header_internal_dependencies.append (t.source_reference.file);
}
}
+
+ public enum SourceFileDependencyType {
+ HEADER_FULL,
+ HEADER_SHALLOW,
+ SOURCE
+ }
}
--- /dev/null
+/* valasourcefilecycle.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;
+
+namespace Vala {
+ public class SourceFileCycle {
+ public List<SourceFile> files;
+ public SourceFile head;
+ }
+}
namespace Vala {
public abstract class Statement : CodeNode {
+ public SourceReference source_reference { get; construct; }
}
}
namespace Vala {
public class Struct : Type_ {
- public string name { get; construct; }
- public SourceReference source_reference { get; construct; }
- public weak Namespace @namespace;
-
List<string> type_parameters;
List<Constant> constants;
List<Field> fields;
}
public void add_method (Method m) {
+ return_if_fail (m != null);
+
methods.append (m);
}
public override ref string get_upper_case_cname (string infix) {
return get_lower_case_cname (infix).up (-1);
}
-
+
public override bool is_reference_type () {
return reference_type;
}
set_cname (((StringLiteral) lit).eval ());
}
}
+ } else if (arg.name.collate ("cheader_filename") == 0) {
+ /* 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)) {
+ cheader_filenames.append (filename);
+ }
+ }
+ }
}
}
}
namespace Vala {
public abstract class Type_ : CodeNode {
+ public string name { get; construct; }
+ public SourceReference source_reference { get; construct; }
+ public Namespace @namespace;
+
public abstract string get_cname ();
public abstract bool is_reference_type ();
public abstract string get_upper_case_cname (string infix);
+
+ public List<string> cheader_filenames;
+ public ref List<string> get_cheader_filenames () {
+ if (cheader_filenames == null) {
+ cheader_filenames = @namespace.get_cheader_filenames ();
+ }
+ return cheader_filenames.copy ();
+ }
}
}
}
public ref string get_cname () {
+ if (type == null && type_parameter == null) {
+ return "void";
+ }
+
string ptr;
string arr;
if (type_parameter == null && !type.is_reference_type () && !is_ref) {
public class WhileStatement : Statement {
public Expression condition { get; construct; }
public Statement body { get; construct; }
- public SourceReference source_reference { get; construct; }
public static ref WhileStatement new (Expression cond, Statement body, SourceReference source) {
return (new WhileStatement (condition = cond, body = body, source_reference = source));
break;
case VALA_EXPRESSION_TYPE_INVOCATION:
vala_code_generator_find_static_type_of_expression (generator, expr->invocation.call);
+ expr->array_type = expr->invocation.call->static_type_symbol->method->return_type->array_type;
expr->static_type_symbol = expr->invocation.call->static_type_symbol->method->return_type->symbol;
break;
case VALA_EXPRESSION_TYPE_IS:
if (!expr->field->is_struct_field) {
fprintf (generator->c_file, ")");
}
- fprintf (generator->c_file, "->%s", expr->member_access.right);
+
+ if ((expr->field->modifiers & VALA_MODIFIER_PRIVATE) != 0) {
+ fprintf (generator->c_file, "->priv->%s", expr->member_access.right);
+ } else {
+ fprintf (generator->c_file, "->%s", expr->member_access.right);
+ }
}
}
}
fprintf (generator->h_file, "\n");
fprintf (generator->h_file, "#include <stdio.h>\n");
+ fprintf (generator->h_file, "#include <string.h>\n");
fprintf (generator->h_file, "#include <glib-object.h>\n");
fprintf (generator->h_file, "\n");