use continue statements to decrease indentation levels add interface
authorJürg Billeter <j@bitron.ch>
Fri, 7 Jul 2006 07:56:56 +0000 (07:56 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 7 Jul 2006 07:56:56 +0000 (07:56 +0000)
2006-07-07  Jürg Billeter  <j@bitron.ch>

* vala/valacodecontext.vala: use continue statements to decrease
  indentation levels
* vala/valasymbolbuilder.vala, vala/valasymbolresolver.vala,
  vala/valasemanticanalyzer.vala, vala/valamemorymanager.vala,
  vala/valacodegenerator.vala, vala/valaconditionalexpression.vala,
  vala/valaconstant.vala: add interface documentation, use implicit
  namespace specification
* vala/valasemanticanalyzer.vala: check that if, while, for, and
  conditional expression conditions are boolean
* vala/valaclass.vala: remove dummy accessor, breaks build with old
  vala compiler
* compiler/valacompiler.vala: use implicit namespace specification
* tests/test-016.vala: test conditional expressions
* tests/Makefile.am: update

svn path=/trunk/; revision=68

13 files changed:
vala/ChangeLog
vala/compiler/valacompiler.vala
vala/tests/Makefile.am
vala/tests/test-016.vala [new file with mode: 0644]
vala/vala/valaclass.vala
vala/vala/valacodecontext.vala
vala/vala/valacodegenerator.vala
vala/vala/valaconditionalexpression.vala
vala/vala/valaconstant.vala
vala/vala/valamemorymanager.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valasymbolbuilder.vala
vala/vala/valasymbolresolver.vala

index 330a0a8..de43c01 100644 (file)
@@ -1,5 +1,22 @@
 2006-07-07  Jürg Billeter  <j@bitron.ch>
 
+       * vala/valacodecontext.vala: use continue statements to decrease
+         indentation levels
+       * vala/valasymbolbuilder.vala, vala/valasymbolresolver.vala,
+         vala/valasemanticanalyzer.vala, vala/valamemorymanager.vala,
+         vala/valacodegenerator.vala, vala/valaconditionalexpression.vala,
+         vala/valaconstant.vala: add interface documentation, use implicit
+         namespace specification
+       * vala/valasemanticanalyzer.vala: check that if, while, for, and
+         conditional expression conditions are boolean
+       * vala/valaclass.vala: remove dummy accessor, breaks build with old
+         vala compiler
+       * compiler/valacompiler.vala: use implicit namespace specification
+       * tests/test-016.vala: test conditional expressions
+       * tests/Makefile.am: update
+
+2006-07-07  Jürg Billeter  <j@bitron.ch>
+
        * vala/valacodecontext.vala: add interface documentation, use implicit
          namespace specification
        * vala/valasymbolbuilder.vala, vala/valasymbolresolver.vala,
index c694439..d9979df 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       class Compiler {
-               static string directory;
-               static bool version;
-               static string[] sources;
-               static string[] vapi_directories;
-               static string library;
-               static string[] packages;
-               static bool disable_memory_management;
-               CodeContext context;
+class Vala.Compiler {
+       static string directory;
+       static bool version;
+       static string[] sources;
+       static string[] vapi_directories;
+       static string library;
+       static string[] packages;
+       static bool disable_memory_management;
+       CodeContext context;
+
+       const OptionEntry[] options = {
+               { "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, out vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
+               { "pkg", 0, 0, OptionArg.STRING_ARRAY, out packages, "Include binding for PACKAGE", "PACKAGE..." },
+               { "library", 0, 0, OptionArg.STRING, out library, "Library name", "NAME" },
+               { "directory", 'd', 0, OptionArg.FILENAME, out directory, "Output directory", "DIRECTORY" },
+               { "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
+               { "disable-memory-management", 0, 0, OptionArg.NONE, ref disable_memory_management, "Disable memory management", null },
+               { "", 0, 0, OptionArg.FILENAME_ARRAY, out sources, null, "FILE..." },
+               { null }
+       };
        
-               const OptionEntry[] options = {
-                       { "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, out vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
-                       { "pkg", 0, 0, OptionArg.STRING_ARRAY, out packages, "Include binding for PACKAGE", "PACKAGE..." },
-                       { "library", 0, 0, OptionArg.STRING, out library, "Library name", "NAME" },
-                       { "directory", 'd', 0, OptionArg.FILENAME, out directory, "Output directory", "DIRECTORY" },
-                       { "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
-                       { "disable-memory-management", 0, 0, OptionArg.NONE, ref disable_memory_management, "Disable memory management", null },
-                       { "", 0, 0, OptionArg.FILENAME_ARRAY, out sources, null, "FILE..." },
-                       { null }
-               };
-               
-               private int quit () {
-                       if (Report.get_errors () == 0) {
-                               stdout.printf ("Compilation succeeded - %d warning(s)\n", Report.get_warnings ());
-                               return 0;
-                       } else {
-                               stdout.printf ("Compilation failed: %d error(s), %d warning(s)\n", Report.get_errors (), Report.get_warnings ());
-                               return 1;
+       private int quit () {
+               if (Report.get_errors () == 0) {
+                       stdout.printf ("Compilation succeeded - %d warning(s)\n", Report.get_warnings ());
+                       return 0;
+               } else {
+                       stdout.printf ("Compilation failed: %d error(s), %d warning(s)\n", Report.get_errors (), Report.get_warnings ());
+                       return 1;
+               }
+       }
+       
+       private ref string get_package_path (string! pkg) {
+               var basename = "%s.vala".printf (pkg);
+       
+               if (vapi_directories != null) {
+                       foreach (string vapidir in vapi_directories) {
+                               var filename = Path.build_filename (vapidir, basename, null);
+                               if (File.test (filename, FileTest.EXISTS)) {
+                                       return filename;
+                               }
                        }
+                       vapi_directories = null;
                }
                
-               private ref string get_package_path (string! pkg) {
-                       var basename = "%s.vala".printf (pkg);
+               var filename = Path.build_filename ("/usr/share/vala/vapi", basename, null);
+               if (File.test (filename, FileTest.EXISTS)) {
+                       return filename;
+               }
                
-                       if (vapi_directories != null) {
-                               foreach (string vapidir in vapi_directories) {
-                                       var filename = Path.build_filename (vapidir, basename, null);
-                                       if (File.test (filename, FileTest.EXISTS)) {
-                                               return filename;
-                                       }
-                               }
-                               vapi_directories = null;
-                       }
-                       
-                       var filename = Path.build_filename ("/usr/share/vala/vapi", basename, null);
-                       if (File.test (filename, FileTest.EXISTS)) {
-                               return filename;
-                       }
-                       
-                       return null;
+               return null;
+       }
+       
+       private bool add_package (string! pkg) {
+               var package_path = get_package_path (pkg);
+               
+               if (package_path == null) {
+                       return false;
                }
                
-               private bool add_package (string! pkg) {
-                       var package_path = get_package_path (pkg);
-                       
-                       if (package_path == null) {
-                               return false;
-                       }
-                       
-                       context.add_source_file (new SourceFile (filename = package_path, pkg = true));
-                       
-                       return true;
+               context.add_source_file (new SourceFile (filename = package_path, pkg = true));
+               
+               return true;
+       }
+       
+       private int run () {
+               context = new CodeContext ();
+               
+               /* default package */
+               if (!add_package ("glib-2.0")) {
+                       Report.error (null, "glib-2.0 not found in specified Vala API directories");
                }
                
-               private int run () {
-                       context = new CodeContext ();
-                       
-                       /* default package */
-                       if (!add_package ("glib-2.0")) {
-                               Report.error (null, "glib-2.0 not found in specified Vala API directories");
-                       }
-                       
-                       if (packages != null) {
-                               foreach (string package in packages) {
-                                       if (!add_package (package)) {
-                                               Report.error (null, "%s not found in specified Vala API directories".printf (package));
-                                       }
-                               }
-                               packages = null;
-                       }
-                       
-                       if (Report.get_errors () > 0) {
-                               return quit ();
-                       }
-                       
-                       foreach (string source in sources) {
-                               if (File.test (source, FileTest.EXISTS)) {
-                                       context.add_source_file (new SourceFile (filename = source));
-                               } else {
-                                       Report.error (null, "%s not found".printf (source));
+               if (packages != null) {
+                       foreach (string package in packages) {
+                               if (!add_package (package)) {
+                                       Report.error (null, "%s not found in specified Vala API directories".printf (package));
                                }
                        }
-                       sources = null;
-                       
-                       if (Report.get_errors () > 0) {
-                               return quit ();
-                       }
-                       
-                       var parser = new Parser ();
-                       parser.parse (context);
-                       
-                       if (Report.get_errors () > 0) {
-                               return quit ();
-                       }
-                       
-                       var builder = new SymbolBuilder ();
-                       builder.build (context);
-                       
-                       if (Report.get_errors () > 0) {
-                               return quit ();
-                       }
-                       
-                       var attributeprocessor = new AttributeProcessor ();
-                       attributeprocessor.process (context);
-                       
-                       if (Report.get_errors () > 0) {
-                               return quit ();
-                       }
-                       
-                       var resolver = new SymbolResolver ();
-                       resolver.resolve (context);
-                       
-                       if (Report.get_errors () > 0) {
-                               return quit ();
-                       }
-                       
-                       var analyzer = new SemanticAnalyzer (memory_management = !disable_memory_management);
-                       analyzer.analyze (context);
-                       
-                       if (Report.get_errors () > 0) {
-                               return quit ();
-                       }
-                       
-                       if (!disable_memory_management) {
-                               var memory_manager = new MemoryManager ();
-                               memory_manager.analyze (context);
-                               
-                               if (Report.get_errors () > 0) {
-                                       return quit ();
-                               }
+                       packages = null;
+               }
+               
+               if (Report.get_errors () > 0) {
+                       return quit ();
+               }
+               
+               foreach (string source in sources) {
+                       if (File.test (source, FileTest.EXISTS)) {
+                               context.add_source_file (new SourceFile (filename = source));
+                       } else {
+                               Report.error (null, "%s not found".printf (source));
                        }
-                       
-                       var code_generator = new CodeGenerator (memory_management = !disable_memory_management);
-                       code_generator.emit (context);
+               }
+               sources = null;
+               
+               if (Report.get_errors () > 0) {
+                       return quit ();
+               }
+               
+               var parser = new Parser ();
+               parser.parse (context);
+               
+               if (Report.get_errors () > 0) {
+                       return quit ();
+               }
+               
+               var builder = new SymbolBuilder ();
+               builder.build (context);
+               
+               if (Report.get_errors () > 0) {
+                       return quit ();
+               }
+               
+               var attributeprocessor = new AttributeProcessor ();
+               attributeprocessor.process (context);
+               
+               if (Report.get_errors () > 0) {
+                       return quit ();
+               }
+               
+               var resolver = new SymbolResolver ();
+               resolver.resolve (context);
+               
+               if (Report.get_errors () > 0) {
+                       return quit ();
+               }
+               
+               var analyzer = new SemanticAnalyzer (memory_management = !disable_memory_management);
+               analyzer.analyze (context);
+               
+               if (Report.get_errors () > 0) {
+                       return quit ();
+               }
+               
+               if (!disable_memory_management) {
+                       var memory_manager = new MemoryManager ();
+                       memory_manager.analyze (context);
                        
                        if (Report.get_errors () > 0) {
                                return quit ();
                        }
-                       
-                       if (library != null) {
-                               var interface_writer = new InterfaceWriter ();
-                               interface_writer.write_file (context, "%s.vala".printf (library));
-                               
-                               library = null;
-                       }
-                       
-                       return quit ();
                }
                
-               static int main (int argc, string[] argv) {
-                       Error err = null;
+               var code_generator = new CodeGenerator (memory_management = !disable_memory_management);
+               code_generator.emit (context);
                
-                       var opt_context = OptionContext.@new ("- Vala Compiler");
-                       opt_context.set_help_enabled (true);
-                       opt_context.add_main_entries (options, null);
-                       opt_context.parse (ref argc, out argv, out err);
-                       
-                       if (err != null) {
-                               return 1;
-                       }
+               if (Report.get_errors () > 0) {
+                       return quit ();
+               }
+               
+               if (library != null) {
+                       var interface_writer = new InterfaceWriter ();
+                       interface_writer.write_file (context, "%s.vala".printf (library));
                        
-                       if (sources == null) {
-                               stderr.printf ("No source file specified.\n");
+                       library = null;
+               }
+               
+               return quit ();
+       }
+       
+       static int main (int argc, string[] argv) {
+               Error err = null;
+       
+               var opt_context = OptionContext.@new ("- Vala Compiler");
+               opt_context.set_help_enabled (true);
+               opt_context.add_main_entries (options, null);
+               opt_context.parse (ref argc, out argv, out err);
+               
+               if (err != null) {
+                       return 1;
+               }
+               
+               if (sources == null) {
+                       stderr.printf ("No source file specified.\n");
+                       return 1;
+               }
+               
+               foreach (string source in sources) {
+                       if (!source.has_suffix (".vala")) {
+                               stderr.printf ("Only .vala source files supported.\n");
                                return 1;
                        }
-                       
-                       foreach (string source in sources) {
-                               if (!source.has_suffix (".vala")) {
-                                       stderr.printf ("Only .vala source files supported.\n");
-                                       return 1;
-                               }
-                       }
-                       
-                       var compiler = new Compiler ();
-                       return compiler.run ();
                }
+               
+               var compiler = new Compiler ();
+               return compiler.run ();
        }
 }
index 2297438..3c56280 100644 (file)
@@ -16,4 +16,5 @@ EXTRA_DIST = \
        test-013.vala \
        test-014.vala \
        test-015.vala \
+       test-016.vala \
        $(NULL)
diff --git a/vala/tests/test-016.vala b/vala/tests/test-016.vala
new file mode 100644 (file)
index 0000000..13dd2f0
--- /dev/null
@@ -0,0 +1,13 @@
+using GLib;
+
+class Maman.Bar {
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Conditional Expression Test: 1");
+               
+               stdout.printf (" %d", false ? -1 : 2);
+               
+               stdout.printf (" 3\n");
+               
+               return 0;
+       }
+}
index 0fe8c1f..476710f 100644 (file)
@@ -44,9 +44,6 @@ public class Vala.Class : DataType {
                get {
                        return _has_private_fields;
                }
-               set {
-                       /* FIXME: dummy accessor due to vala compiler bug */
-               }
        }
        
        private string cname;
index 9c9405d..f38726a 100644 (file)
@@ -76,10 +76,12 @@ public class Vala.CodeContext {
                /* 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);
-                               }
+                       if (file.pkg) {
+                               continue;
+                       }
+                       
+                       if (file.mark == 0) {
+                               visit (file, null);
                        }
                }
                
@@ -96,18 +98,20 @@ public class Vala.CodeContext {
                 */
                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 ());
+                       if (file2.pkg) {
+                               continue;
+                       }
+
+                       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 ());
                                }
                        }
                }
@@ -143,60 +147,69 @@ public class Vala.CodeContext {
                file.mark = 1;
                
                foreach (SourceFile dep in file.header_internal_dependencies) {
-                       if (file != dep) {
-                               if (dep.mark == 1) {
-                                       /* found cycle */
+                       if (file == dep) {
+                               continue;
+                       }
+                       
+                       if (dep.mark == 1) {
+                               /* found cycle */
+                               
+                               var cycle = new SourceFileCycle ();
+                               cycles.append (cycle);
+                               
+                               bool cycle_start_found = false;
+                               foreach (SourceFile cycle_file in l) {
+                                       ref SourceFileCycle ref_cycle_file_cycle = cycle_file.cycle;
+                                       if (!cycle_start_found) {
+                                               if (cycle_file == dep) {
+                                                       cycle_start_found = true;
+                                               }
+                                       }
                                        
-                                       var cycle = new SourceFileCycle ();
-                                       cycles.append (cycle);
+                                       if (!cycle_start_found) {
+                                               continue;
+                                       }
                                        
-                                       bool cycle_start_found = false;
-                                       foreach (SourceFile cycle_file in l) {
-                                               ref SourceFileCycle ref_cycle_file_cycle = cycle_file.cycle;
-                                               if (!cycle_start_found) {
-                                                       if (cycle_file == dep) {
-                                                               cycle_start_found = true;
+                                       if (cycle_file.cycle != null) {
+                                               /* file already in a cycle */
+                                               
+                                               if (cycle_file.cycle == cycle) {
+                                                       /* file is in the same cycle, nothing to do */
+                                                       continue;
+                                               }
+                                               
+                                               /* file is in an other cycle, merge the two cycles */
+                                               
+                                               /* broken memory management cycles.remove (cycle_file.cycle); */
+                                               ref List<ref SourceFileCycle> newlist = null;
+                                               foreach (SourceFileCycle oldcycle in cycles) {
+                                                       if (oldcycle != cycle_file.cycle) {
+                                                               newlist.append (oldcycle);
                                                        }
                                                }
-                                               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 */
-                                                                       
-                                                                       /* broken memory management cycles.remove (cycle_file.cycle); */
-                                                                       ref List<ref SourceFileCycle> newlist = null;
-                                                                       foreach (SourceFileCycle oldcycle in cycles) {
-                                                                               if (oldcycle != cycle_file.cycle) {
-                                                                                       newlist.append (oldcycle);
-                                                                               }
-                                                                       }
-                                                                       cycles = null;
-                                                                       foreach (SourceFileCycle newcycle in newlist) {
-                                                                               cycles.append (newcycle);
-                                                                       }
-                                                                       newlist = null;
-                                                                       /* end workaround for broken memory management */
-                                                                       
-                                                                       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;
+                                               cycles = null;
+                                               foreach (SourceFileCycle newcycle in newlist) {
+                                                       cycles.append (newcycle);
+                                               }
+                                               newlist = null;
+                                               /* end workaround for broken memory management */
+                                               
+                                               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);
                                }
+                       } else if (dep.mark == 0) {
+                               /* found not yet visited file */
+                               
+                               visit (dep, l);
                        }
                }
                
index 627ac9c..ceea93e 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class CodeGenerator : CodeVisitor {
-               public bool memory_management { get; construct; }
-               
-               Symbol current_symbol;
-               Symbol current_type_symbol;
-
-               CCodeFragment header_begin;
-               CCodeFragment header_type_declaration;
-               CCodeFragment header_type_definition;
-               CCodeFragment header_type_member_declaration;
-               CCodeFragment source_begin;
-               CCodeFragment source_include_directives;
-               CCodeFragment source_type_member_declaration;
-               CCodeFragment source_type_member_definition;
-               
-               CCodeStruct instance_struct;
-               CCodeStruct type_struct;
-               CCodeStruct instance_priv_struct;
-               CCodeEnum prop_enum;
-               CCodeEnum cenum;
-               CCodeFunction function;
-               CCodeBlock block;
-               
-               /* all temporary variables */
-               List<VariableDeclarator> temp_vars;
-               /* temporary variables that own their content */
-               List<VariableDeclarator> temp_ref_vars;
-               
-               private int next_temp_var_id = 0;
-
-               public void emit (CodeContext! context) {
-                       context.find_header_cycles ();
-               
-                       /* we're only interested in non-pkg source files */
-                       var source_files = context.get_source_files ();
-                       foreach (SourceFile file in source_files) {
-                               if (!file.pkg) {
-                                       file.accept (this);
-                               }
+/**
+ * Code visitor generating C Code.
+ */
+public class Vala.CodeGenerator : CodeVisitor {
+       /**
+        * Specifies whether automatic memory management is active.
+        */
+       public bool memory_management { get; set; }
+       
+       Symbol current_symbol;
+       Symbol current_type_symbol;
+
+       CCodeFragment header_begin;
+       CCodeFragment header_type_declaration;
+       CCodeFragment header_type_definition;
+       CCodeFragment header_type_member_declaration;
+       CCodeFragment source_begin;
+       CCodeFragment source_include_directives;
+       CCodeFragment source_type_member_declaration;
+       CCodeFragment source_type_member_definition;
+       
+       CCodeStruct instance_struct;
+       CCodeStruct type_struct;
+       CCodeStruct instance_priv_struct;
+       CCodeEnum prop_enum;
+       CCodeEnum cenum;
+       CCodeFunction function;
+       CCodeBlock block;
+       
+       /* all temporary variables */
+       List<VariableDeclarator> temp_vars;
+       /* temporary variables that own their content */
+       List<VariableDeclarator> temp_ref_vars;
+       
+       private int next_temp_var_id = 0;
+
+       /**
+        * Generate and emit C code for the specified code context.
+        *
+        * @param context a code context
+        */
+       public void emit (CodeContext! context) {
+               context.find_header_cycles ();
+       
+               /* we're only interested in non-pkg source files */
+               var source_files = context.get_source_files ();
+               foreach (SourceFile file in source_files) {
+                       if (!file.pkg) {
+                               file.accept (this);
                        }
                }
-       
-               public override void visit_begin_source_file (SourceFile! source_file) {
-                       header_begin = new CCodeFragment ();
-                       header_type_declaration = new CCodeFragment ();
-                       header_type_definition = new CCodeFragment ();
-                       header_type_member_declaration = new CCodeFragment ();
-                       source_begin = new CCodeFragment ();
-                       source_include_directives = new CCodeFragment ();
-                       source_type_member_declaration = new CCodeFragment ();
-                       source_type_member_definition = new CCodeFragment ();
-                       
-                       next_temp_var_id = 0;
-                       
-                       header_begin.append (new CCodeIncludeDirective (filename = "glib.h"));
-                       source_include_directives.append (new CCodeIncludeDirective (filename = source_file.get_cheader_filename ()));
-                       
-                       ref List<string> used_includes = null;
-                       used_includes.append ("glib.h");
-                       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);
-                               }
+       }
+
+       public override void visit_begin_source_file (SourceFile! source_file) {
+               header_begin = new CCodeFragment ();
+               header_type_declaration = new CCodeFragment ();
+               header_type_definition = new CCodeFragment ();
+               header_type_member_declaration = new CCodeFragment ();
+               source_begin = new CCodeFragment ();
+               source_include_directives = new CCodeFragment ();
+               source_type_member_declaration = new CCodeFragment ();
+               source_type_member_definition = new CCodeFragment ();
+               
+               next_temp_var_id = 0;
+               
+               header_begin.append (new CCodeIncludeDirective (filename = "glib.h"));
+               source_include_directives.append (new CCodeIncludeDirective (filename = source_file.get_cheader_filename ()));
+               
+               ref List<string> used_includes = null;
+               used_includes.append ("glib.h");
+               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 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);
-                               }
+               }
+               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) {
-                                       var namespaces = cycle_file.get_namespaces ();
-                                       foreach (Namespace ns in namespaces) {
-                                               var structs = ns.get_structs ();
-                                               foreach (Struct st in structs) {
-                                                       header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (st.get_cname ()), declarator = new CCodeVariableDeclarator (name = st.get_cname ())));
-                                               }
-                                               var classes = ns.get_classes ();
-                                               foreach (Class cl in classes) {
-                                                       header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (cl.get_cname ()), declarator = new CCodeVariableDeclarator (name = cl.get_cname ())));
-                                                       header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%sClass".printf (cl.get_cname ()), declarator = new CCodeVariableDeclarator (name = "%sClass".printf (cl.get_cname ()))));
-                                               }
+               }
+               if (source_file.is_cycle_head) {
+                       foreach (SourceFile cycle_file in source_file.cycle.files) {
+                               var namespaces = cycle_file.get_namespaces ();
+                               foreach (Namespace ns in namespaces) {
+                                       var structs = ns.get_structs ();
+                                       foreach (Struct st in structs) {
+                                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (st.get_cname ()), declarator = new CCodeVariableDeclarator (name = st.get_cname ())));
+                                       }
+                                       var classes = ns.get_classes ();
+                                       foreach (Class cl in classes) {
+                                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (cl.get_cname ()), declarator = new CCodeVariableDeclarator (name = cl.get_cname ())));
+                                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%sClass".printf (cl.get_cname ()), declarator = new CCodeVariableDeclarator (name = "%sClass".printf (cl.get_cname ()))));
                                        }
                                }
                        }
                }
+       }
+       
+       private static ref string get_define_for_filename (string! filename) {
+               var define = String.new ("__");
                
-               private static ref string get_define_for_filename (string! filename) {
-                       var define = String.new ("__");
-                       
-                       var i = filename;
-                       while (i.len () > 0) {
-                               var c = i.get_char ();
-                               /* FIXME: remove explicit cast when implicit cast works */
-                               if (c.isalnum  () && c < (unichar) 128) {
-                                       define.append_unichar (c.toupper ());
-                               } else {
-                                       define.append_c ('_');
-                               }
-                       
-                               i = i.next_char ();
+               var i = filename;
+               while (i.len () > 0) {
+                       var c = i.get_char ();
+                       /* FIXME: remove explicit cast when implicit cast works */
+                       if (c.isalnum  () && c < (unichar) 128) {
+                               define.append_unichar (c.toupper ());
+                       } else {
+                               define.append_c ('_');
                        }
-                       
-                       define.append ("__");
-                       
-                       return define.str;
+               
+                       i = i.next_char ();
                }
                
-               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 (filename = source_file.get_cheader_filename ());
-                       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 (filename = source_file.get_csource_filename ());
-                       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;
-                       header_type_declaration = null;
-                       header_type_definition = null;
-                       header_type_member_declaration = null;
-                       source_begin = null;
-                       source_include_directives = null;
-                       source_type_member_declaration = null;
-                       source_type_member_definition = null;
-               }
-
-               public override void visit_begin_class (Class! cl) {
-                       current_symbol = cl.symbol;
-                       current_type_symbol = cl.symbol;
-
-                       instance_struct = new CCodeStruct (name = "_%s".printf (cl.get_cname ()));
-                       type_struct = new CCodeStruct (name = "_%sClass".printf (cl.get_cname ()));
-                       instance_priv_struct = new CCodeStruct (name = "_%sPrivate".printf (cl.get_cname ()));
-                       prop_enum = new CCodeEnum ();
-                       prop_enum.add_value ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null)), null);
-                       
-                       
-                       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));
+               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 (filename = source_file.get_cheader_filename ());
+               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 (filename = source_file.get_csource_filename ());
+               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;
+               header_type_declaration = null;
+               header_type_definition = null;
+               header_type_member_declaration = null;
+               source_begin = null;
+               source_include_directives = null;
+               source_type_member_declaration = null;
+               source_type_member_definition = null;
+       }
 
-                       macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
-                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (cl.get_upper_case_cname (null)), replacement = macro));
+       public override void visit_begin_class (Class! cl) {
+               current_symbol = cl.symbol;
+               current_type_symbol = cl.symbol;
 
-                       macro = "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
-                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s_CLASS(klass)".printf (cl.get_upper_case_cname (null)), replacement = macro));
+               instance_struct = new CCodeStruct (name = "_%s".printf (cl.get_cname ()));
+               type_struct = new CCodeStruct (name = "_%sClass".printf (cl.get_cname ()));
+               instance_priv_struct = new CCodeStruct (name = "_%sPrivate".printf (cl.get_cname ()));
+               prop_enum = new CCodeEnum ();
+               prop_enum.add_value ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null)), null);
+               
+               
+               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_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
-                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (cl.get_upper_case_cname ("IS_")), replacement = macro));
+               macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (cl.get_upper_case_cname (null)), replacement = macro));
 
-                       macro = "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
-                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s_CLASS(klass)".printf (cl.get_upper_case_cname ("IS_")), replacement = macro));
+               macro = "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement (name = "%s_CLASS(klass)".printf (cl.get_upper_case_cname (null)), 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 ());
+               macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
+               header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (cl.get_upper_case_cname ("IS_")), replacement = macro));
 
+               macro = "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl.get_upper_case_cname ("TYPE_"));
+               header_type_declaration.append (new CCodeMacroReplacement (name = "%s_CLASS(klass)".printf (cl.get_upper_case_cname ("IS_")), replacement = macro));
 
-                       if (cl.source_reference.file.cycle == null) {
-                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (instance_struct.name), declarator = new CCodeVariableDeclarator (name = cl.get_cname ())));
-                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (type_struct.name), declarator = new CCodeVariableDeclarator (name = "%sClass".printf (cl.get_cname ()))));
-                       }
-                       header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (instance_priv_struct.name), declarator = new CCodeVariableDeclarator (name = "%sPrivate".printf (cl.get_cname ()))));
-                       
-                       instance_struct.add_field (cl.base_class.get_cname (), "parent");
-                       instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
-                       type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent");
+               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 ());
 
-                       if (cl.source_reference.comment != null) {
-                               header_type_definition.append (new CCodeComment (text = cl.source_reference.comment));
-                       }
-                       header_type_definition.append (instance_struct);
-                       header_type_definition.append (type_struct);
-                       source_type_member_declaration.append (instance_priv_struct);
-                       macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
-                       source_type_member_declaration.append (new CCodeMacroReplacement (name = "%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), replacement = macro));
-                       source_type_member_declaration.append (prop_enum);
-               }
-               
-               public override void visit_end_class (Class! cl) {
-                       add_get_property_function (cl);
-                       add_set_property_function (cl);
-                       add_class_init_function (cl);
-                       add_instance_init_function (cl);
-                       if (memory_management) {
-                               add_dispose_function (cl);
-                       }
-                       
-                       var type_fun = new ClassRegisterFunction (class_reference = cl);
-                       type_fun.init_from_type ();
-                       header_type_member_declaration.append (type_fun.get_declaration ());
-                       source_type_member_definition.append (type_fun);
 
-                       current_type_symbol = null;
+               if (cl.source_reference.file.cycle == null) {
+                       header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (instance_struct.name), declarator = new CCodeVariableDeclarator (name = cl.get_cname ())));
+                       header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (type_struct.name), declarator = new CCodeVariableDeclarator (name = "%sClass".printf (cl.get_cname ()))));
                }
+               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (instance_priv_struct.name), declarator = new CCodeVariableDeclarator (name = "%sPrivate".printf (cl.get_cname ()))));
                
-               private void add_class_init_function (Class! cl) {
-                       var class_init = new CCodeFunction (name = "%s_class_init".printf (cl.get_lower_case_cname (null)), return_type = "void");
-                       class_init.add_parameter (new CCodeFormalParameter (type_name = "%sClass *".printf (cl.get_cname ()), name = "klass"));
-                       class_init.modifiers = CCodeModifiers.STATIC;
-                       
-                       var init_block = new CCodeBlock ();
-                       class_init.block = init_block;
-                       
-                       ref CCodeFunctionCall ccall;
-                       
-                       if (cl.has_private_fields) {
-                               ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_add_private"));
-                               ccall.add_argument (new CCodeIdentifier (name = "klass"));
-                               ccall.add_argument (new CCodeConstant (name = "sizeof (%sPrivate)".printf (cl.get_cname ())));
-                               init_block.add_statement (new CCodeExpressionStatement (expression = ccall));
-                       }
-                       
-                       ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
+               instance_struct.add_field (cl.base_class.get_cname (), "parent");
+               instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
+               type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent");
+
+               if (cl.source_reference.comment != null) {
+                       header_type_definition.append (new CCodeComment (text = cl.source_reference.comment));
+               }
+               header_type_definition.append (instance_struct);
+               header_type_definition.append (type_struct);
+               source_type_member_declaration.append (instance_priv_struct);
+               macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
+               source_type_member_declaration.append (new CCodeMacroReplacement (name = "%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), replacement = macro));
+               source_type_member_declaration.append (prop_enum);
+       }
+       
+       public override void visit_end_class (Class! cl) {
+               add_get_property_function (cl);
+               add_set_property_function (cl);
+               add_class_init_function (cl);
+               add_instance_init_function (cl);
+               if (memory_management) {
+                       add_dispose_function (cl);
+               }
+               
+               var type_fun = new ClassRegisterFunction (class_reference = cl);
+               type_fun.init_from_type ();
+               header_type_member_declaration.append (type_fun.get_declaration ());
+               source_type_member_definition.append (type_fun);
+
+               current_type_symbol = null;
+       }
+       
+       private void add_class_init_function (Class! cl) {
+               var class_init = new CCodeFunction (name = "%s_class_init".printf (cl.get_lower_case_cname (null)), return_type = "void");
+               class_init.add_parameter (new CCodeFormalParameter (type_name = "%sClass *".printf (cl.get_cname ()), name = "klass"));
+               class_init.modifiers = CCodeModifiers.STATIC;
+               
+               var init_block = new CCodeBlock ();
+               class_init.block = init_block;
+               
+               ref CCodeFunctionCall ccall;
+               
+               if (cl.has_private_fields) {
+                       ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_add_private"));
                        ccall.add_argument (new CCodeIdentifier (name = "klass"));
-                       init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccall, member_name = "get_property", is_pointer = true), right = new CCodeIdentifier (name = "%s_get_property".printf (cl.get_lower_case_cname (null))))));
-                       init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccall, member_name = "set_property", is_pointer = true), right = new CCodeIdentifier (name = "%s_set_property".printf (cl.get_lower_case_cname (null))))));
+                       ccall.add_argument (new CCodeConstant (name = "sizeof (%sPrivate)".printf (cl.get_cname ())));
+                       init_block.add_statement (new CCodeExpressionStatement (expression = ccall));
+               }
+               
+               ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
+               ccall.add_argument (new CCodeIdentifier (name = "klass"));
+               init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccall, member_name = "get_property", is_pointer = true), right = new CCodeIdentifier (name = "%s_get_property".printf (cl.get_lower_case_cname (null))))));
+               init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccall, member_name = "set_property", is_pointer = true), right = new CCodeIdentifier (name = "%s_set_property".printf (cl.get_lower_case_cname (null))))));
+               
+               if (cl.constructor != null) {
+                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
+                       ccast.add_argument (new CCodeIdentifier (name = "klass"));
+                       init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccast, member_name = "constructor", is_pointer = true), right = new CCodeIdentifier (name = "%s_constructor".printf (cl.get_lower_case_cname (null))))));
+               }
+
+               if (memory_management && cl.get_fields () != null) {
+                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
+                       ccast.add_argument (new CCodeIdentifier (name = "klass"));
+                       init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccast, member_name = "dispose", is_pointer = true), right = new CCodeIdentifier (name = "%s_dispose".printf (cl.get_lower_case_cname (null))))));
+               }
+               
+               var methods = cl.get_methods ();
+               foreach (Method m in methods) {
+                       if (m.is_virtual || m.is_override) {
+                               var base_type = m.base_method.symbol.parent_symbol.node;
                        
-                       if (cl.constructor != null) {
-                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
+                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
                                ccast.add_argument (new CCodeIdentifier (name = "klass"));
-                               init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccast, member_name = "constructor", is_pointer = true), right = new CCodeIdentifier (name = "%s_constructor".printf (cl.get_lower_case_cname (null))))));
+                               init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccast, member_name = m.name, is_pointer = true), right = new CCodeIdentifier (name = m.get_real_cname ()))));
                        }
-
-                       if (memory_management && cl.get_fields () != null) {
-                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
-                               ccast.add_argument (new CCodeIdentifier (name = "klass"));
-                               init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccast, member_name = "dispose", is_pointer = true), right = new CCodeIdentifier (name = "%s_dispose".printf (cl.get_lower_case_cname (null))))));
+               }
+               
+               var props = cl.get_properties ();
+               foreach (Property prop in props) {
+                       var cinst = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_class_install_property"));
+                       cinst.add_argument (ccall);
+                       cinst.add_argument (new CCodeConstant (name = prop.get_upper_case_cname ()));
+                       var cspec = new CCodeFunctionCall ();
+                       cspec.add_argument (prop.get_canonical_cconstant ());
+                       cspec.add_argument (new CCodeConstant (name = "\"foo\""));
+                       cspec.add_argument (new CCodeConstant (name = "\"bar\""));
+                       if (prop.type_reference.type is Class) {
+                               cspec.call = new CCodeIdentifier (name = "g_param_spec_object");
+                               cspec.add_argument (new CCodeIdentifier (name = prop.type_reference.type.get_upper_case_cname ("TYPE_")));
+                       } else if (prop.type_reference.type_name == "string") {
+                               cspec.call = new CCodeIdentifier (name = "g_param_spec_string");
+                               cspec.add_argument (new CCodeConstant (name = "NULL"));
+                       } else if (prop.type_reference.type_name == "int"
+                                  || prop.type_reference.type is Enum) {
+                               cspec.call = new CCodeIdentifier (name = "g_param_spec_int");
+                               cspec.add_argument (new CCodeConstant (name = "G_MININT"));
+                               cspec.add_argument (new CCodeConstant (name = "G_MAXINT"));
+                               cspec.add_argument (new CCodeConstant (name = "0"));
+                       } else if (prop.type_reference.type_name == "bool") {
+                               cspec.call = new CCodeIdentifier (name = "g_param_spec_boolean");
+                               cspec.add_argument (new CCodeConstant (name = "FALSE"));
+                       } else {
+                               cspec.call = new CCodeIdentifier (name = "g_param_spec_pointer");
                        }
                        
-                       var methods = cl.get_methods ();
-                       foreach (Method m in methods) {
-                               if (m.is_virtual || m.is_override) {
-                                       var base_type = m.base_method.symbol.parent_symbol.node;
-                               
-                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
-                                       ccast.add_argument (new CCodeIdentifier (name = "klass"));
-                                       init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = ccast, member_name = m.name, is_pointer = true), right = new CCodeIdentifier (name = m.get_real_cname ()))));
-                               }
+                       var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
+                       if (prop.get_accessor != null) {
+                               pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
                        }
-                       
-                       var props = cl.get_properties ();
-                       foreach (Property prop in props) {
-                               var cinst = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_class_install_property"));
-                               cinst.add_argument (ccall);
-                               cinst.add_argument (new CCodeConstant (name = prop.get_upper_case_cname ()));
-                               var cspec = new CCodeFunctionCall ();
-                               cspec.add_argument (prop.get_canonical_cconstant ());
-                               cspec.add_argument (new CCodeConstant (name = "\"foo\""));
-                               cspec.add_argument (new CCodeConstant (name = "\"bar\""));
-                               if (prop.type_reference.type is Class) {
-                                       cspec.call = new CCodeIdentifier (name = "g_param_spec_object");
-                                       cspec.add_argument (new CCodeIdentifier (name = prop.type_reference.type.get_upper_case_cname ("TYPE_")));
-                               } else if (prop.type_reference.type_name == "string") {
-                                       cspec.call = new CCodeIdentifier (name = "g_param_spec_string");
-                                       cspec.add_argument (new CCodeConstant (name = "NULL"));
-                               } else if (prop.type_reference.type_name == "int"
-                                          || prop.type_reference.type is Enum) {
-                                       cspec.call = new CCodeIdentifier (name = "g_param_spec_int");
-                                       cspec.add_argument (new CCodeConstant (name = "G_MININT"));
-                                       cspec.add_argument (new CCodeConstant (name = "G_MAXINT"));
-                                       cspec.add_argument (new CCodeConstant (name = "0"));
-                               } else if (prop.type_reference.type_name == "bool") {
-                                       cspec.call = new CCodeIdentifier (name = "g_param_spec_boolean");
-                                       cspec.add_argument (new CCodeConstant (name = "FALSE"));
-                               } else {
-                                       cspec.call = new CCodeIdentifier (name = "g_param_spec_pointer");
-                               }
-                               
-                               var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
-                               if (prop.get_accessor != null) {
-                                       pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
-                               }
-                               if (prop.set_accessor != null) {
-                                       pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
-                                       if (prop.set_accessor.construct_) {
-                                               if (prop.set_accessor.writable) {
-                                                       pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
-                                               } else {
-                                                       pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
-                                               }
+                       if (prop.set_accessor != null) {
+                               pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
+                               if (prop.set_accessor.construct_) {
+                                       if (prop.set_accessor.writable) {
+                                               pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
+                                       } else {
+                                               pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
                                        }
                                }
-                               cspec.add_argument (new CCodeConstant (name = pflags));
-                               cinst.add_argument (cspec);
-                               
-                               init_block.add_statement (new CCodeExpressionStatement (expression = cinst));
                        }
+                       cspec.add_argument (new CCodeConstant (name = pflags));
+                       cinst.add_argument (cspec);
                        
-                       source_type_member_definition.append (class_init);
+                       init_block.add_statement (new CCodeExpressionStatement (expression = cinst));
                }
                
-               private void add_instance_init_function (Class! cl) {
-                       var instance_init = new CCodeFunction (name = "%s_init".printf (cl.get_lower_case_cname (null)), return_type = "void");
-                       instance_init.add_parameter (new CCodeFormalParameter (type_name = "%s *".printf (cl.get_cname ()), name = "self"));
-                       instance_init.modifiers = CCodeModifiers.STATIC;
-                       
-                       var init_block = new CCodeBlock ();
-                       instance_init.block = init_block;
-                       
-                       if (cl.has_private_fields) {
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
-                               ccall.add_argument (new CCodeIdentifier (name = "self"));
-                               init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "self"), member_name = "priv", is_pointer = true), right = ccall)));
-                       }
-                       
-                       var fields = cl.get_fields ();
-                       foreach (Field f in fields) {
-                               if (f.initializer != null) {
-                                       ref CCodeExpression lhs = null;
-                                       if (f.instance) {
-                                               if (f.access == MemberAccessibility.PRIVATE) {
-                                                       lhs = new CCodeMemberAccess (inner = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "self"), member_name = "priv", is_pointer = true), member_name = f.get_cname (), is_pointer = true);
-                                               } else {
-                                                       lhs = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "self"), member_name = f.get_cname (), is_pointer = true);
-                                               }
-                                       } /* else {
-                                               lhs = new CCodeIdentifier (name = "%s_%s".printf (cl.get_lower_case_cname (null), f.get_cname ()));
-                                       } */
-                                       if (lhs != null)  {
-                                               init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = lhs, right = f.initializer.ccodenode)));
+               source_type_member_definition.append (class_init);
+       }
+       
+       private void add_instance_init_function (Class! cl) {
+               var instance_init = new CCodeFunction (name = "%s_init".printf (cl.get_lower_case_cname (null)), return_type = "void");
+               instance_init.add_parameter (new CCodeFormalParameter (type_name = "%s *".printf (cl.get_cname ()), name = "self"));
+               instance_init.modifiers = CCodeModifiers.STATIC;
+               
+               var init_block = new CCodeBlock ();
+               instance_init.block = init_block;
+               
+               if (cl.has_private_fields) {
+                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
+                       ccall.add_argument (new CCodeIdentifier (name = "self"));
+                       init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "self"), member_name = "priv", is_pointer = true), right = ccall)));
+               }
+               
+               var fields = cl.get_fields ();
+               foreach (Field f in fields) {
+                       if (f.initializer != null) {
+                               ref CCodeExpression lhs = null;
+                               if (f.instance) {
+                                       if (f.access == MemberAccessibility.PRIVATE) {
+                                               lhs = new CCodeMemberAccess (inner = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "self"), member_name = "priv", is_pointer = true), member_name = f.get_cname (), is_pointer = true);
+                                       } else {
+                                               lhs = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "self"), member_name = f.get_cname (), is_pointer = true);
                                        }
+                               } /* else {
+                                       lhs = new CCodeIdentifier (name = "%s_%s".printf (cl.get_lower_case_cname (null), f.get_cname ()));
+                               } */
+                               if (lhs != null)  {
+                                       init_block.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = lhs, right = f.initializer.ccodenode)));
                                }
                        }
-                       
-                       var init_sym = cl.symbol.lookup ("init");
-                       if (init_sym != null) {
-                               var init_fun = (Method) init_sym.node;
-                               init_block.add_statement (init_fun.body.ccodenode);
-                       }
-                       
-                       source_type_member_definition.append (instance_init);
                }
                
-               private void add_dispose_function (Class! cl) {
-                       function = new CCodeFunction (name = "%s_dispose".printf (cl.get_lower_case_cname (null)), return_type = "void");
-                       function.modifiers = CCodeModifiers.STATIC;
-                       
-                       function.add_parameter (new CCodeFormalParameter (name = "obj", type_name = "GObject *"));
-                       
-                       source_type_member_declaration.append (function.copy ());
-
+               var init_sym = cl.symbol.lookup ("init");
+               if (init_sym != null) {
+                       var init_fun = (Method) init_sym.node;
+                       init_block.add_statement (init_fun.body.ccodenode);
+               }
+               
+               source_type_member_definition.append (instance_init);
+       }
+       
+       private void add_dispose_function (Class! cl) {
+               function = new CCodeFunction (name = "%s_dispose".printf (cl.get_lower_case_cname (null)), return_type = "void");
+               function.modifiers = CCodeModifiers.STATIC;
+               
+               function.add_parameter (new CCodeFormalParameter (name = "obj", type_name = "GObject *"));
+               
+               source_type_member_declaration.append (function.copy ());
 
-                       var cblock = new CCodeBlock ();
 
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
-                       ccall.add_argument (new CCodeIdentifier (name = "obj"));
-                       
-                       var cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
-                       
-                       cblock.add_statement (cdecl);
-                       
-                       
-                       var fields = cl.get_fields ();
-                       foreach (Field f in fields) {
-                               if (f.instance && f.type_reference.is_lvalue_ref) {
-                                       var cself = new CCodeIdentifier (name = "self");
-                                       CCodeExpression cstruct = cself;
-                                       if (f.access == MemberAccessibility.PRIVATE) {
-                                               cstruct = new CCodeMemberAccess (inner = cself, member_name = "priv", is_pointer = true);
-                                       }
-                                       var cfield = new CCodeMemberAccess (inner = cstruct, member_name = f.get_cname (), is_pointer = true);
+               var cblock = new CCodeBlock ();
 
-                                       cblock.add_statement (new CCodeExpressionStatement (expression = get_unref_expression (cfield, f.type_reference)));
+               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
+               ccall.add_argument (new CCodeIdentifier (name = "obj"));
+               
+               var cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
+               
+               cblock.add_statement (cdecl);
+               
+               
+               var fields = cl.get_fields ();
+               foreach (Field f in fields) {
+                       if (f.instance && f.type_reference.is_lvalue_ref) {
+                               var cself = new CCodeIdentifier (name = "self");
+                               CCodeExpression cstruct = cself;
+                               if (f.access == MemberAccessibility.PRIVATE) {
+                                       cstruct = new CCodeMemberAccess (inner = cself, member_name = "priv", is_pointer = true);
                                }
-                       }
+                               var cfield = new CCodeMemberAccess (inner = cstruct, member_name = f.get_cname (), is_pointer = true);
 
+                               cblock.add_statement (new CCodeExpressionStatement (expression = get_unref_expression (cfield, f.type_reference)));
+                       }
+               }
 
-                       cdecl = new CCodeDeclaration (type_name = "%sClass *".printf (cl.get_cname ()));
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "klass"));
-                       cblock.add_statement (cdecl);
 
-                       cdecl = new CCodeDeclaration (type_name = "GObjectClass *");
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "parent_class"));
-                       cblock.add_statement (cdecl);
-       
-       
-                       ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_peek"));
-                       ccall.add_argument (new CCodeIdentifier (name = cl.get_upper_case_cname ("TYPE_")));
-                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_CLASS".printf (cl.get_upper_case_cname (null))));
-                       ccast.add_argument (ccall);
-                       cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "klass"), right = ccast)));
+               cdecl = new CCodeDeclaration (type_name = "%sClass *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "klass"));
+               cblock.add_statement (cdecl);
 
-                       ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_peek_parent"));
-                       ccall.add_argument (new CCodeIdentifier (name = "klass"));
-                       ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
-                       ccast.add_argument (ccall);
-                       cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "parent_class"), right = ccast)));
+               cdecl = new CCodeDeclaration (type_name = "GObjectClass *");
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "parent_class"));
+               cblock.add_statement (cdecl);
 
-                       
-                       ccall = new CCodeFunctionCall (call = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "parent_class"), member_name = "dispose", is_pointer = true));
-                       ccall.add_argument (new CCodeIdentifier (name = "obj"));
-                       cblock.add_statement (new CCodeExpressionStatement (expression = ccall));
 
+               ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_peek"));
+               ccall.add_argument (new CCodeIdentifier (name = cl.get_upper_case_cname ("TYPE_")));
+               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_CLASS".printf (cl.get_upper_case_cname (null))));
+               ccast.add_argument (ccall);
+               cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "klass"), right = ccast)));
 
-                       function.block = cblock;
+               ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_peek_parent"));
+               ccall.add_argument (new CCodeIdentifier (name = "klass"));
+               ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
+               ccast.add_argument (ccall);
+               cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "parent_class"), right = ccast)));
 
-                       source_type_member_definition.append (function);
-               }
                
-               private void add_get_property_function (Class! cl) {
-                       var get_prop = new CCodeFunction (name = "%s_get_property".printf (cl.get_lower_case_cname (null)), return_type = "void");
-                       get_prop.add_parameter (new CCodeFormalParameter (type_name = "GObject *", name = "object"));
-                       get_prop.add_parameter (new CCodeFormalParameter (type_name = "guint", name = "property_id"));
-                       get_prop.add_parameter (new CCodeFormalParameter (type_name = "GValue *", name = "value"));
-                       get_prop.add_parameter (new CCodeFormalParameter (type_name = "GParamSpec *", name = "pspec"));
-                       
-                       var block = new CCodeBlock ();
-                       
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
-                       ccall.add_argument (new CCodeIdentifier (name = "object"));
-                       var cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
-                       block.add_statement (cdecl);
-                       
-                       var cswitch = new CCodeSwitchStatement (expression = new CCodeIdentifier (name = "property_id"));
-                       var props = cl.get_properties ();
-                       foreach (Property prop in props) {
-                               if (prop.get_accessor == null) {
-                                       continue;
-                               }
+               ccall = new CCodeFunctionCall (call = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "parent_class"), member_name = "dispose", is_pointer = true));
+               ccall.add_argument (new CCodeIdentifier (name = "obj"));
+               cblock.add_statement (new CCodeExpressionStatement (expression = ccall));
 
-                               var ccase = new CCodeCaseStatement (expression = new CCodeIdentifier (name = prop.get_upper_case_cname ()));
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name)));
-                               ccall.add_argument (new CCodeIdentifier (name = "self"));
-                               var csetcall = new CCodeFunctionCall ();
-                               if (prop.type_reference.type is Class) {
-                                       csetcall.call = new CCodeIdentifier (name = "g_value_set_object");
-                               } else if (prop.type_reference.type_name == "string") {
-                                       csetcall.call = new CCodeIdentifier (name = "g_value_set_string");
-                               } else if (prop.type_reference.type_name == "int"
-                                          || prop.type_reference.type is Enum) {
-                                       csetcall.call = new CCodeIdentifier (name = "g_value_set_int");
-                               } else if (prop.type_reference.type_name == "bool") {
-                                       csetcall.call = new CCodeIdentifier (name = "g_value_set_boolean");
-                               } else {
-                                       csetcall.call = new CCodeIdentifier (name = "g_value_set_pointer");
-                               }
-                               csetcall.add_argument (new CCodeIdentifier (name = "value"));
-                               csetcall.add_argument (ccall);
-                               ccase.add_statement (new CCodeExpressionStatement (expression = csetcall));
-                               ccase.add_statement (new CCodeBreakStatement ());
-                               cswitch.add_case (ccase);
-                       }
-                       block.add_statement (cswitch);
 
-                       get_prop.block = block;
-                       
-                       source_type_member_definition.append (get_prop);
-               }
+               function.block = cblock;
+
+               source_type_member_definition.append (function);
+       }
+       
+       private void add_get_property_function (Class! cl) {
+               var get_prop = new CCodeFunction (name = "%s_get_property".printf (cl.get_lower_case_cname (null)), return_type = "void");
+               get_prop.add_parameter (new CCodeFormalParameter (type_name = "GObject *", name = "object"));
+               get_prop.add_parameter (new CCodeFormalParameter (type_name = "guint", name = "property_id"));
+               get_prop.add_parameter (new CCodeFormalParameter (type_name = "GValue *", name = "value"));
+               get_prop.add_parameter (new CCodeFormalParameter (type_name = "GParamSpec *", name = "pspec"));
                
-               private void add_set_property_function (Class! cl) {
-                       var set_prop = new CCodeFunction (name = "%s_set_property".printf (cl.get_lower_case_cname (null)), return_type = "void");
-                       set_prop.add_parameter (new CCodeFormalParameter (type_name = "GObject *", name = "object"));
-                       set_prop.add_parameter (new CCodeFormalParameter (type_name = "guint", name = "property_id"));
-                       set_prop.add_parameter (new CCodeFormalParameter (type_name = "const GValue *", name = "value"));
-                       set_prop.add_parameter (new CCodeFormalParameter (type_name = "GParamSpec *", name = "pspec"));
-                       
-                       var block = new CCodeBlock ();
-                       
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
-                       ccall.add_argument (new CCodeIdentifier (name = "object"));
-                       var cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
-                       block.add_statement (cdecl);
-                       
-                       var cswitch = new CCodeSwitchStatement (expression = new CCodeIdentifier (name = "property_id"));
-                       var props = cl.get_properties ();
-                       foreach (Property prop in props) {
-                               if (prop.set_accessor == null) {
-                                       continue;
-                               }
+               var block = new CCodeBlock ();
+               
+               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
+               ccall.add_argument (new CCodeIdentifier (name = "object"));
+               var cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
+               block.add_statement (cdecl);
+               
+               var cswitch = new CCodeSwitchStatement (expression = new CCodeIdentifier (name = "property_id"));
+               var props = cl.get_properties ();
+               foreach (Property prop in props) {
+                       if (prop.get_accessor == null) {
+                               continue;
+                       }
+
+                       var ccase = new CCodeCaseStatement (expression = new CCodeIdentifier (name = prop.get_upper_case_cname ()));
+                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name)));
+                       ccall.add_argument (new CCodeIdentifier (name = "self"));
+                       var csetcall = new CCodeFunctionCall ();
+                       if (prop.type_reference.type is Class) {
+                               csetcall.call = new CCodeIdentifier (name = "g_value_set_object");
+                       } else if (prop.type_reference.type_name == "string") {
+                               csetcall.call = new CCodeIdentifier (name = "g_value_set_string");
+                       } else if (prop.type_reference.type_name == "int"
+                                  || prop.type_reference.type is Enum) {
+                               csetcall.call = new CCodeIdentifier (name = "g_value_set_int");
+                       } else if (prop.type_reference.type_name == "bool") {
+                               csetcall.call = new CCodeIdentifier (name = "g_value_set_boolean");
+                       } else {
+                               csetcall.call = new CCodeIdentifier (name = "g_value_set_pointer");
+                       }
+                       csetcall.add_argument (new CCodeIdentifier (name = "value"));
+                       csetcall.add_argument (ccall);
+                       ccase.add_statement (new CCodeExpressionStatement (expression = csetcall));
+                       ccase.add_statement (new CCodeBreakStatement ());
+                       cswitch.add_case (ccase);
+               }
+               block.add_statement (cswitch);
 
-                               var ccase = new CCodeCaseStatement (expression = new CCodeIdentifier (name = prop.get_upper_case_cname ()));
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name)));
-                               ccall.add_argument (new CCodeIdentifier (name = "self"));
-                               var cgetcall = new CCodeFunctionCall ();
-                               if (prop.type_reference.type is Class) {
-                                       cgetcall.call = new CCodeIdentifier (name = "g_value_get_object");
-                               } else if (prop.type_reference.type_name == "string") {
-                                       cgetcall.call = new CCodeIdentifier (name = "g_value_get_string");
-                               } else if (prop.type_reference.type_name == "int"
-                                         || prop.type_reference.type is Enum) {
-                                       cgetcall.call = new CCodeIdentifier (name = "g_value_get_int");
-                               } else if (prop.type_reference.type_name == "bool") {
-                                       cgetcall.call = new CCodeIdentifier (name = "g_value_get_boolean");
-                               } else {
-                                       cgetcall.call = new CCodeIdentifier (name = "g_value_get_pointer");
-                               }
-                               cgetcall.add_argument (new CCodeIdentifier (name = "value"));
-                               ccall.add_argument (cgetcall);
-                               ccase.add_statement (new CCodeExpressionStatement (expression = ccall));
-                               ccase.add_statement (new CCodeBreakStatement ());
-                               cswitch.add_case (ccase);
+               get_prop.block = block;
+               
+               source_type_member_definition.append (get_prop);
+       }
+       
+       private void add_set_property_function (Class! cl) {
+               var set_prop = new CCodeFunction (name = "%s_set_property".printf (cl.get_lower_case_cname (null)), return_type = "void");
+               set_prop.add_parameter (new CCodeFormalParameter (type_name = "GObject *", name = "object"));
+               set_prop.add_parameter (new CCodeFormalParameter (type_name = "guint", name = "property_id"));
+               set_prop.add_parameter (new CCodeFormalParameter (type_name = "const GValue *", name = "value"));
+               set_prop.add_parameter (new CCodeFormalParameter (type_name = "GParamSpec *", name = "pspec"));
+               
+               var block = new CCodeBlock ();
+               
+               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
+               ccall.add_argument (new CCodeIdentifier (name = "object"));
+               var cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
+               block.add_statement (cdecl);
+               
+               var cswitch = new CCodeSwitchStatement (expression = new CCodeIdentifier (name = "property_id"));
+               var props = cl.get_properties ();
+               foreach (Property prop in props) {
+                       if (prop.set_accessor == null) {
+                               continue;
+                       }
+
+                       var ccase = new CCodeCaseStatement (expression = new CCodeIdentifier (name = prop.get_upper_case_cname ()));
+                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name)));
+                       ccall.add_argument (new CCodeIdentifier (name = "self"));
+                       var cgetcall = new CCodeFunctionCall ();
+                       if (prop.type_reference.type is Class) {
+                               cgetcall.call = new CCodeIdentifier (name = "g_value_get_object");
+                       } else if (prop.type_reference.type_name == "string") {
+                               cgetcall.call = new CCodeIdentifier (name = "g_value_get_string");
+                       } else if (prop.type_reference.type_name == "int"
+                                 || prop.type_reference.type is Enum) {
+                               cgetcall.call = new CCodeIdentifier (name = "g_value_get_int");
+                       } else if (prop.type_reference.type_name == "bool") {
+                               cgetcall.call = new CCodeIdentifier (name = "g_value_get_boolean");
+                       } else {
+                               cgetcall.call = new CCodeIdentifier (name = "g_value_get_pointer");
                        }
-                       block.add_statement (cswitch);
-                       
-                       set_prop.block = block;
-                       
-                       source_type_member_definition.append (set_prop);
+                       cgetcall.add_argument (new CCodeIdentifier (name = "value"));
+                       ccall.add_argument (cgetcall);
+                       ccase.add_statement (new CCodeExpressionStatement (expression = ccall));
+                       ccase.add_statement (new CCodeBreakStatement ());
+                       cswitch.add_case (ccase);
                }
+               block.add_statement (cswitch);
                
-               public override void visit_begin_struct (Struct! st) {
-                       instance_struct = new CCodeStruct (name = "_%s".printf (st.name));
+               set_prop.block = block;
+               
+               source_type_member_definition.append (set_prop);
+       }
+       
+       public override void visit_begin_struct (Struct! st) {
+               instance_struct = new CCodeStruct (name = "_%s".printf (st.name));
 
-                       if (st.source_reference.comment != null) {
-                               header_type_definition.append (new CCodeComment (text = st.source_reference.comment));
-                       }
-                       header_type_definition.append (instance_struct);
+               if (st.source_reference.comment != null) {
+                       header_type_definition.append (new CCodeComment (text = st.source_reference.comment));
                }
+               header_type_definition.append (instance_struct);
+       }
 
-               public override void visit_begin_interface (Interface! iface) {
-                       current_symbol = iface.symbol;
-                       current_type_symbol = iface.symbol;
+       public override void visit_begin_interface (Interface! iface) {
+               current_symbol = iface.symbol;
+               current_type_symbol = iface.symbol;
 
-                       type_struct = new CCodeStruct (name = "_%sInterface".printf (iface.get_cname ()));
-                       
-                       header_type_declaration.append (new CCodeNewline ());
-                       var macro = "(%s_get_type ())".printf (iface.get_lower_case_cname (null));
-                       header_type_declaration.append (new CCodeMacroReplacement (name = iface.get_upper_case_cname ("TYPE_"), replacement = macro));
+               type_struct = new CCodeStruct (name = "_%sInterface".printf (iface.get_cname ()));
+               
+               header_type_declaration.append (new CCodeNewline ());
+               var macro = "(%s_get_type ())".printf (iface.get_lower_case_cname (null));
+               header_type_declaration.append (new CCodeMacroReplacement (name = iface.get_upper_case_cname ("TYPE_"), replacement = macro));
 
-                       macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
-                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (iface.get_upper_case_cname (null)), replacement = macro));
+               macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (iface.get_upper_case_cname (null)), replacement = macro));
 
-                       macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface.get_upper_case_cname ("TYPE_"));
-                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (iface.get_upper_case_cname ("IS_")), replacement = macro));
+               macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface.get_upper_case_cname ("TYPE_"));
+               header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (iface.get_upper_case_cname ("IS_")), replacement = macro));
 
-                       macro = "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %sInterface))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
-                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s_GET_INTERFACE(obj)".printf (iface.get_upper_case_cname (null)), replacement = macro));
-                       header_type_declaration.append (new CCodeNewline ());
+               macro = "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %sInterface))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
+               header_type_declaration.append (new CCodeMacroReplacement (name = "%s_GET_INTERFACE(obj)".printf (iface.get_upper_case_cname (null)), replacement = macro));
+               header_type_declaration.append (new CCodeNewline ());
 
 
-                       if (iface.source_reference.file.cycle == null) {
-                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (iface.get_cname ()), declarator = new CCodeVariableDeclarator (name = iface.get_cname ())));
-                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (type_struct.name), declarator = new CCodeVariableDeclarator (name = "%sInterface".printf (iface.get_cname ()))));
-                       }
-                       
-                       type_struct.add_field ("GTypeInterface", "parent");
+               if (iface.source_reference.file.cycle == null) {
+                       header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (iface.get_cname ()), declarator = new CCodeVariableDeclarator (name = iface.get_cname ())));
+                       header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (type_struct.name), declarator = new CCodeVariableDeclarator (name = "%sInterface".printf (iface.get_cname ()))));
+               }
+               
+               type_struct.add_field ("GTypeInterface", "parent");
 
-                       if (iface.source_reference.comment != null) {
-                               header_type_definition.append (new CCodeComment (text = iface.source_reference.comment));
-                       }
-                       header_type_definition.append (type_struct);
+               if (iface.source_reference.comment != null) {
+                       header_type_definition.append (new CCodeComment (text = iface.source_reference.comment));
                }
+               header_type_definition.append (type_struct);
+       }
 
-               public override void visit_end_interface (Interface! iface) {
-                       var type_fun = new InterfaceRegisterFunction (interface_reference = iface);
-                       type_fun.init_from_type ();
-                       header_type_member_declaration.append (type_fun.get_declaration ());
-                       source_type_member_definition.append (type_fun);
+       public override void visit_end_interface (Interface! iface) {
+               var type_fun = new InterfaceRegisterFunction (interface_reference = iface);
+               type_fun.init_from_type ();
+               header_type_member_declaration.append (type_fun.get_declaration ());
+               source_type_member_definition.append (type_fun);
 
-                       current_type_symbol = null;
-               }
-               
-               public override void visit_begin_enum (Enum! en) {
-                       cenum = new CCodeEnum (name = en.get_cname ());
+               current_type_symbol = null;
+       }
+       
+       public override void visit_begin_enum (Enum! en) {
+               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 (cenum);
+               if (en.source_reference.comment != null) {
+                       header_type_definition.append (new CCodeComment (text = en.source_reference.comment));
                }
+               header_type_definition.append (cenum);
+       }
 
-               public override void visit_enum_value (EnumValue! ev) {
-                       cenum.add_value (ev.get_cname (), null);
-               }
+       public override void visit_enum_value (EnumValue! ev) {
+               cenum.add_value (ev.get_cname (), null);
+       }
 
-               public override void visit_end_callback (Callback! cb) {
-                       var ctypedef = new CCodeTypeDefinition ();
-                       
-                       ctypedef.type_name = cb.return_type.get_cname ();
-                       
-                       var cfundecl = new CCodeFunctionDeclarator (name = cb.get_cname ());
-                       foreach (FormalParameter param in cb.get_parameters ()) {
-                               cfundecl.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                       }
-                       ctypedef.declarator = cfundecl;
-                       
-                       if (cb.access == MemberAccessibility.PUBLIC) {
-                               header_type_declaration.append (ctypedef);
-                       } else {
-                               source_type_member_declaration.append (ctypedef);
-                       }
+       public override void visit_end_callback (Callback! cb) {
+               var ctypedef = new CCodeTypeDefinition ();
+               
+               ctypedef.type_name = cb.return_type.get_cname ();
+               
+               var cfundecl = new CCodeFunctionDeclarator (name = cb.get_cname ());
+               foreach (FormalParameter param in cb.get_parameters ()) {
+                       cfundecl.add_parameter ((CCodeFormalParameter) param.ccodenode);
+               }
+               ctypedef.declarator = cfundecl;
+               
+               if (cb.access == MemberAccessibility.PUBLIC) {
+                       header_type_declaration.append (ctypedef);
+               } else {
+                       source_type_member_declaration.append (ctypedef);
                }
+       }
 
-               public override void visit_constant (Constant! c) {
-                       if (c.symbol.parent_symbol.node is DataType) {
-                               var t = (DataType) c.symbol.parent_symbol.node;
-                               var cdecl = new CCodeDeclaration (type_name = c.type_reference.get_const_cname ());
-                               var arr = "";
-                               if (c.type_reference.array) {
-                                       arr = "[]";
-                               }
-                               cdecl.add_declarator (new CCodeVariableDeclarator (name = "%s%s".printf (c.get_cname (), arr), initializer = c.initializer.ccodenode));
-                               cdecl.modifiers = CCodeModifiers.STATIC;
-                               source_type_member_declaration.append (cdecl);
+       public override void visit_constant (Constant! c) {
+               if (c.symbol.parent_symbol.node is DataType) {
+                       var t = (DataType) c.symbol.parent_symbol.node;
+                       var cdecl = new CCodeDeclaration (type_name = c.type_reference.get_const_cname ());
+                       var arr = "";
+                       if (c.type_reference.array) {
+                               arr = "[]";
                        }
+                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "%s%s".printf (c.get_cname (), arr), initializer = c.initializer.ccodenode));
+                       cdecl.modifiers = CCodeModifiers.STATIC;
+                       source_type_member_declaration.append (cdecl);
                }
-               
-               public override void visit_field (Field! f) {
-                       if (f.access == MemberAccessibility.PUBLIC) {
-                               instance_struct.add_field (f.type_reference.get_cname (), f.get_cname ());
-                       } else if (f.access == MemberAccessibility.PRIVATE) {
-                               if (f.instance) {
-                                       instance_priv_struct.add_field (f.type_reference.get_cname (), f.get_cname ());
-                               } else {
-                                       if (f.symbol.parent_symbol.node is DataType) {
-                                               var t = (DataType) f.symbol.parent_symbol.node;
-                                               var cdecl = new CCodeDeclaration (type_name = f.type_reference.get_cname ());
-                                               var var_decl = new CCodeVariableDeclarator (name = "%s_%s".printf (t.get_lower_case_cname (null), f.get_cname ()));
-                                               if (f.initializer != null) {
-                                                       var_decl.initializer = (CCodeExpression) f.initializer.ccodenode;
-                                               }
-                                               cdecl.add_declarator (var_decl);
-                                               cdecl.modifiers = CCodeModifiers.STATIC;
-                                               source_type_member_declaration.append (cdecl);
+       }
+       
+       public override void visit_field (Field! f) {
+               if (f.access == MemberAccessibility.PUBLIC) {
+                       instance_struct.add_field (f.type_reference.get_cname (), f.get_cname ());
+               } else if (f.access == MemberAccessibility.PRIVATE) {
+                       if (f.instance) {
+                               instance_priv_struct.add_field (f.type_reference.get_cname (), f.get_cname ());
+                       } else {
+                               if (f.symbol.parent_symbol.node is DataType) {
+                                       var t = (DataType) f.symbol.parent_symbol.node;
+                                       var cdecl = new CCodeDeclaration (type_name = f.type_reference.get_cname ());
+                                       var var_decl = new CCodeVariableDeclarator (name = "%s_%s".printf (t.get_lower_case_cname (null), f.get_cname ()));
+                                       if (f.initializer != null) {
+                                               var_decl.initializer = (CCodeExpression) f.initializer.ccodenode;
                                        }
+                                       cdecl.add_declarator (var_decl);
+                                       cdecl.modifiers = CCodeModifiers.STATIC;
+                                       source_type_member_declaration.append (cdecl);
                                }
                        }
                }
+       }
 
-               public override void visit_begin_method (Method! m) {
-                       current_symbol = m.symbol;
+       public override void visit_begin_method (Method! m) {
+               current_symbol = m.symbol;
+       }
+       
+       private ref CCodeStatement create_method_type_check_statement (Method! m, DataType! t, bool non_null, string! var_name) {
+               return create_type_check_statement (m, m.return_type.type, t, non_null, var_name);
+       }
+       
+       private ref CCodeStatement create_property_type_check_statement (Property! prop, bool getter, DataType! t, bool non_null, string! var_name) {
+               if (getter) {
+                       return create_type_check_statement (prop, prop.type_reference.type, t, non_null, var_name);
+               } else {
+                       return create_type_check_statement (prop, null, t, non_null, var_name);
                }
+       }
+       
+       private ref CCodeStatement create_type_check_statement (CodeNode! method_node, DataType ret_type, DataType! t, bool non_null, string! var_name) {
+               var ccheck = new CCodeFunctionCall ();
                
-               private ref CCodeStatement create_method_type_check_statement (Method! m, DataType! t, bool non_null, string! var_name) {
-                       return create_type_check_statement (m, m.return_type.type, t, non_null, var_name);
+               var ctype_check = new CCodeFunctionCall (call = new CCodeIdentifier (name = t.get_upper_case_cname ("IS_")));
+               ctype_check.add_argument (new CCodeIdentifier (name = var_name));
+               
+               ref CCodeExpression cexpr = ctype_check;
+               if (!non_null) {
+                       var cnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = new CCodeIdentifier (name = var_name), right = new CCodeConstant (name = "NULL"));
+               
+                       cexpr = new CCodeBinaryExpression (operator = CCodeBinaryOperator.OR, left = cnull, right = ctype_check);
                }
+               ccheck.add_argument (cexpr);
                
-               private ref CCodeStatement create_property_type_check_statement (Property! prop, bool getter, DataType! t, bool non_null, string! var_name) {
-                       if (getter) {
-                               return create_type_check_statement (prop, prop.type_reference.type, t, non_null, var_name);
+               if (ret_type == null) {
+                       /* void function */
+                       ccheck.call = new CCodeIdentifier (name = "g_return_if_fail");
+               } else {
+                       ccheck.call = new CCodeIdentifier (name = "g_return_val_if_fail");
+                       
+                       if (ret_type.is_reference_type ()) {
+                               ccheck.add_argument (new CCodeConstant (name = "NULL"));
+                       } else if (ret_type.name == "bool") {
+                               ccheck.add_argument (new CCodeConstant (name = "FALSE"));
+                       } else if (ret_type.name == "int" || ret_type is Enum || ret_type is Flags) {
+                               ccheck.add_argument (new CCodeConstant (name = "0"));
                        } else {
-                               return create_type_check_statement (prop, null, t, non_null, var_name);
+                               Report.error (method_node.source_reference, "not supported return type for runtime type checks");
+                               return null;
                        }
                }
                
-               private ref CCodeStatement create_type_check_statement (CodeNode! method_node, DataType ret_type, DataType! t, bool non_null, string! var_name) {
-                       var ccheck = new CCodeFunctionCall ();
-                       
-                       var ctype_check = new CCodeFunctionCall (call = new CCodeIdentifier (name = t.get_upper_case_cname ("IS_")));
-                       ctype_check.add_argument (new CCodeIdentifier (name = var_name));
-                       
-                       ref CCodeExpression cexpr = ctype_check;
-                       if (!non_null) {
-                               var cnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = new CCodeIdentifier (name = var_name), right = new CCodeConstant (name = "NULL"));
-                       
-                               cexpr = new CCodeBinaryExpression (operator = CCodeBinaryOperator.OR, left = cnull, right = ctype_check);
+               return new CCodeExpressionStatement (expression = ccheck);
+       }
+
+       private DataType find_parent_type (CodeNode node) {
+               var sym = node.symbol;
+               while (sym != null) {
+                       if (sym.node is DataType) {
+                               return (DataType) sym.node;
                        }
-                       ccheck.add_argument (cexpr);
-                       
-                       if (ret_type == null) {
-                               /* void function */
-                               ccheck.call = new CCodeIdentifier (name = "g_return_if_fail");
+                       sym = sym.parent_symbol;
+               }
+               return null;
+       }
+
+       public override void visit_end_method (Method! m) {
+               current_symbol = current_symbol.parent_symbol;
+
+               if (m.name == "init") {
+                       return;
+               }
+       
+               function = new CCodeFunction (name = m.get_real_cname (), return_type = m.return_type.get_cname ());
+               CCodeFunctionDeclarator vdeclarator = 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);
                        } else {
-                               ccheck.call = new CCodeIdentifier (name = "g_return_val_if_fail");
-                               
-                               if (ret_type.is_reference_type ()) {
-                                       ccheck.add_argument (new CCodeConstant (name = "NULL"));
-                               } else if (ret_type.name == "bool") {
-                                       ccheck.add_argument (new CCodeConstant (name = "FALSE"));
-                               } else if (ret_type.name == "int" || ret_type is Enum || ret_type is Flags) {
-                                       ccheck.add_argument (new CCodeConstant (name = "0"));
-                               } else {
-                                       Report.error (method_node.source_reference, "not supported return type for runtime type checks");
-                                       return null;
-                               }
+                               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);
                        }
-                       
-                       return new CCodeExpressionStatement (expression = ccheck);
-               }
+                       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);
 
-               private DataType find_parent_type (CodeNode node) {
-                       var sym = node.symbol;
-                       while (sym != null) {
-                               if (sym.node is DataType) {
-                                       return (DataType) sym.node;
-                               }
-                               sym = sym.parent_symbol;
+                               var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
+                               vdeclarator.add_parameter (cparam);
                        }
-                       return null;
                }
-
-               public override void visit_end_method (Method! m) {
-                       current_symbol = current_symbol.parent_symbol;
-
-                       if (m.name == "init") {
-                               return;
+               
+               var params = m.get_parameters ();
+               foreach (FormalParameter param in params) {
+                       function.add_parameter ((CCodeFormalParameter) param.ccodenode);
+                       if (vdeclarator != null) {
+                               vdeclarator.add_parameter ((CCodeFormalParameter) param.ccodenode);
                        }
+               }
                
-                       function = new CCodeFunction (name = m.get_real_cname (), return_type = m.return_type.get_cname ());
-                       CCodeFunctionDeclarator vdeclarator = 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);
-                               } 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);
+               /* 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)) {
+                               /* public methods need function declaration in
+                                * header file except virtual/overridden methods */
+                               header_type_member_declaration.append (function.copy ());
+                       } else {
+                               /* declare all other functions in source file to
+                                * avoid dependency on order within source file */
+                               function.modifiers |= CCodeModifiers.STATIC;
+                               source_type_member_declaration.append (function.copy ());
+                       }
+                       
+                       /* Methods imported from a plain C file don't
+                        * have a body, e.g. Vala.Parser.parse_file () */
+                       if (m.body != null) {
+                               function.block = (CCodeBlock) m.body.ccodenode;
+
+                               var cinit = new CCodeFragment ();
+                               function.block.prepend_statement (cinit);
+
+                               if (m.symbol.parent_symbol.node is Class) {
+                                       var cl = (Class) m.symbol.parent_symbol.node;
+                                       if (m.is_override) {
+                                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
+                                               ccall.add_argument (new CCodeIdentifier (name = "base"));
+                                               
+                                               var cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
+                                               cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
+                                               
+                                               cinit.append (cdecl);
+                                       } else if (m.instance) {
+                                               cinit.append (create_method_type_check_statement (m, cl, true, "self"));
+                                       }
+                               }
+                               foreach (FormalParameter param in m.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));
+                                       }
                                }
-                               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);
+
+                               if (m.source_reference != null && m.source_reference.comment != null) {
+                                       source_type_member_definition.append (new CCodeComment (text = m.source_reference.comment));
                                }
+                               source_type_member_definition.append (function);
                        }
-                       
-                       var params = m.get_parameters ();
-                       foreach (FormalParameter param in params) {
-                               function.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                               if (vdeclarator != null) {
-                                       vdeclarator.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                               }
-                       }
-                       
-                       /* 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)) {
-                                       /* public methods need function declaration in
-                                        * header file except virtual/overridden methods */
-                                       header_type_member_declaration.append (function.copy ());
-                               } else {
-                                       /* declare all other functions in source file to
-                                        * avoid dependency on order within source file */
-                                       function.modifiers |= CCodeModifiers.STATIC;
-                                       source_type_member_declaration.append (function.copy ());
-                               }
-                               
-                               /* Methods imported from a plain C file don't
-                                * have a body, e.g. Vala.Parser.parse_file () */
-                               if (m.body != null) {
-                                       function.block = (CCodeBlock) m.body.ccodenode;
-
-                                       var cinit = new CCodeFragment ();
-                                       function.block.prepend_statement (cinit);
-
-                                       if (m.symbol.parent_symbol.node is Class) {
-                                               var cl = (Class) m.symbol.parent_symbol.node;
-                                               if (m.is_override) {
-                                                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
-                                                       ccall.add_argument (new CCodeIdentifier (name = "base"));
-                                                       
-                                                       var cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
-                                                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
-                                                       
-                                                       cinit.append (cdecl);
-                                               } else if (m.instance) {
-                                                       cinit.append (create_method_type_check_statement (m, cl, true, "self"));
-                                               }
-                                       }
-                                       foreach (FormalParameter param in m.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));
-                                               }
-                                       }
-
-                                       if (m.source_reference != null && m.source_reference.comment != null) {
-                                               source_type_member_definition.append (new CCodeComment (text = m.source_reference.comment));
-                                       }
-                                       source_type_member_definition.append (function);
-                               }
-                       }
-                       
-                       if (m.is_abstract || m.is_virtual) {
-                               var cl = (Class) m.symbol.parent_symbol.node;
+               }
+               
+               if (m.is_abstract || m.is_virtual) {
+                       var cl = (Class) m.symbol.parent_symbol.node;
 
-                               var vfunc = new CCodeFunction (name = m.get_cname (), return_type = m.return_type.get_cname ());
+                       var vfunc = new CCodeFunction (name = m.get_cname (), return_type = m.return_type.get_cname ());
 
-                               var this_type = new TypeReference ();
-                               this_type.type = (DataType) m.symbol.parent_symbol.node;
+                       var this_type = new TypeReference ();
+                       this_type.type = (DataType) m.symbol.parent_symbol.node;
 
-                               var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
-                               vfunc.add_parameter (cparam);
-                               
-                               var vblock = new CCodeBlock ();
-                               
-                               var vcast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
-                               vcast.add_argument (new CCodeIdentifier (name = "self"));
+                       var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
+                       vfunc.add_parameter (cparam);
                        
-                               var vcall = new CCodeFunctionCall (call = new CCodeMemberAccess (inner = vcast, member_name = m.name, is_pointer = true));
-                               vcall.add_argument (new CCodeIdentifier (name = "self"));
+                       var vblock = new CCodeBlock ();
                        
-                               var params = m.get_parameters ();
-                               foreach (FormalParameter param in params) {
-                                       vfunc.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                                       vcall.add_argument (new CCodeIdentifier (name = param.name));
-                               }
+                       var vcast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
+                       vcast.add_argument (new CCodeIdentifier (name = "self"));
+               
+                       var vcall = new CCodeFunctionCall (call = new CCodeMemberAccess (inner = vcast, member_name = m.name, is_pointer = true));
+                       vcall.add_argument (new CCodeIdentifier (name = "self"));
+               
+                       var params = m.get_parameters ();
+                       foreach (FormalParameter param in params) {
+                               vfunc.add_parameter ((CCodeFormalParameter) param.ccodenode);
+                               vcall.add_argument (new CCodeIdentifier (name = param.name));
+                       }
 
-                               vblock.add_statement (new CCodeExpressionStatement (expression = vcall));
+                       vblock.add_statement (new CCodeExpressionStatement (expression = vcall));
 
-                               header_type_member_declaration.append (vfunc.copy ());
-                               
-                               vfunc.block = vblock;
-                               
-                               source_type_member_definition.append (vfunc);
-                       }
+                       header_type_member_declaration.append (vfunc.copy ());
                        
-                       if (m.name == "main") {
-                               var cmain = new CCodeFunction (name = "main", return_type = "int");
-                               cmain.add_parameter (new CCodeFormalParameter (type_name = "int", name = "argc"));
-                               cmain.add_parameter (new CCodeFormalParameter (type_name = "char **", name = "argv"));
-                               var main_block = new CCodeBlock ();
-                               main_block.add_statement (new CCodeExpressionStatement (expression = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_init"))));
-                               var main_call = new CCodeFunctionCall (call = new CCodeIdentifier (name = function.name));
-                               main_call.add_argument (new CCodeIdentifier (name = "argc"));
-                               main_call.add_argument (new CCodeIdentifier (name = "argv"));
-                               main_block.add_statement (new CCodeReturnStatement (return_expression = main_call));
-                               cmain.block = main_block;
-                               source_type_member_definition.append (cmain);
-                       }
+                       vfunc.block = vblock;
+                       
+                       source_type_member_definition.append (vfunc);
                }
                
-               public override void visit_formal_parameter (FormalParameter! p) {
-                       if (!p.ellipsis) {
-                               p.ccodenode = new CCodeFormalParameter (type_name = p.type_reference.get_cname (), name = p.name);
-                       }
+               if (m.name == "main") {
+                       var cmain = new CCodeFunction (name = "main", return_type = "int");
+                       cmain.add_parameter (new CCodeFormalParameter (type_name = "int", name = "argc"));
+                       cmain.add_parameter (new CCodeFormalParameter (type_name = "char **", name = "argv"));
+                       var main_block = new CCodeBlock ();
+                       main_block.add_statement (new CCodeExpressionStatement (expression = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_init"))));
+                       var main_call = new CCodeFunctionCall (call = new CCodeIdentifier (name = function.name));
+                       main_call.add_argument (new CCodeIdentifier (name = "argc"));
+                       main_call.add_argument (new CCodeIdentifier (name = "argv"));
+                       main_block.add_statement (new CCodeReturnStatement (return_expression = main_call));
+                       cmain.block = main_block;
+                       source_type_member_definition.append (cmain);
                }
-
-               public override void visit_end_property (Property! prop) {
-                       prop_enum.add_value (prop.get_upper_case_cname (), null);
+       }
+       
+       public override void visit_formal_parameter (FormalParameter! p) {
+               if (!p.ellipsis) {
+                       p.ccodenode = new CCodeFormalParameter (type_name = p.type_reference.get_cname (), name = p.name);
                }
+       }
 
-               public override void visit_end_property_accessor (PropertyAccessor! acc) {
-                       var prop = (Property) acc.symbol.parent_symbol.node;
-                       var cl = (Class) prop.symbol.parent_symbol.node;
-                       
-                       if (acc.readable) {
-                               function = new CCodeFunction (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name), return_type = prop.type_reference.get_cname ());
-                       } else {
-                               function = new CCodeFunction (name = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name), return_type = "void");
-                       }
-                       var this_type = new TypeReference ();
-                       this_type.type = cl;
-                       var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
-                       function.add_parameter (cparam);
-                       if (acc.writable || acc.construct_) {
-                               function.add_parameter (new CCodeFormalParameter (type_name = prop.type_reference.get_cname (), name = "value"));
-                       }
-                       
-                       header_type_member_declaration.append (function.copy ());
-                       
-                       if (acc.body != null) {
-                               function.block = (CCodeBlock) acc.body.ccodenode;
+       public override void visit_end_property (Property! prop) {
+               prop_enum.add_value (prop.get_upper_case_cname (), null);
+       }
 
-                               function.block.prepend_statement (create_property_type_check_statement (prop, acc.readable, cl, true, "self"));
-                       }
-                       
-                       source_type_member_definition.append (function);
+       public override void visit_end_property_accessor (PropertyAccessor! acc) {
+               var prop = (Property) acc.symbol.parent_symbol.node;
+               var cl = (Class) prop.symbol.parent_symbol.node;
+               
+               if (acc.readable) {
+                       function = new CCodeFunction (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name), return_type = prop.type_reference.get_cname ());
+               } else {
+                       function = new CCodeFunction (name = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name), return_type = "void");
+               }
+               var this_type = new TypeReference ();
+               this_type.type = cl;
+               var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
+               function.add_parameter (cparam);
+               if (acc.writable || acc.construct_) {
+                       function.add_parameter (new CCodeFormalParameter (type_name = prop.type_reference.get_cname (), name = "value"));
                }
                
-               public override void visit_end_constructor (Constructor! c) {
-                       var cl = (Class) c.symbol.parent_symbol.node;
+               header_type_member_declaration.append (function.copy ());
                
-                       function = new CCodeFunction (name = "%s_constructor".printf (cl.get_lower_case_cname (null)), return_type = "GObject *");
-                       function.modifiers = CCodeModifiers.STATIC;
-                       
-                       function.add_parameter (new CCodeFormalParameter (name = "type", type_name = "GType"));
-                       function.add_parameter (new CCodeFormalParameter (name = "n_construct_properties", type_name = "guint"));
-                       function.add_parameter (new CCodeFormalParameter (name = "construct_properties", type_name = "GObjectConstructParam *"));
-                       
-                       source_type_member_declaration.append (function.copy ());
+               if (acc.body != null) {
+                       function.block = (CCodeBlock) acc.body.ccodenode;
 
+                       function.block.prepend_statement (create_property_type_check_statement (prop, acc.readable, cl, true, "self"));
+               }
+               
+               source_type_member_definition.append (function);
+       }
+       
+       public override void visit_end_constructor (Constructor! c) {
+               var cl = (Class) c.symbol.parent_symbol.node;
+       
+               function = new CCodeFunction (name = "%s_constructor".printf (cl.get_lower_case_cname (null)), return_type = "GObject *");
+               function.modifiers = CCodeModifiers.STATIC;
+               
+               function.add_parameter (new CCodeFormalParameter (name = "type", type_name = "GType"));
+               function.add_parameter (new CCodeFormalParameter (name = "n_construct_properties", type_name = "guint"));
+               function.add_parameter (new CCodeFormalParameter (name = "construct_properties", type_name = "GObjectConstructParam *"));
+               
+               source_type_member_declaration.append (function.copy ());
 
-                       var cblock = new CCodeBlock ();
-                       var cdecl = new CCodeDeclaration (type_name = "GObject *");
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "obj"));
-                       cblock.add_statement (cdecl);
 
-                       cdecl = new CCodeDeclaration (type_name = "%sClass *".printf (cl.get_cname ()));
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "klass"));
-                       cblock.add_statement (cdecl);
+               var cblock = new CCodeBlock ();
+               var cdecl = new CCodeDeclaration (type_name = "GObject *");
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "obj"));
+               cblock.add_statement (cdecl);
 
-                       cdecl = new CCodeDeclaration (type_name = "GObjectClass *");
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "parent_class"));
-                       cblock.add_statement (cdecl);
-       
-       
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_peek"));
-                       ccall.add_argument (new CCodeIdentifier (name = cl.get_upper_case_cname ("TYPE_")));
-                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_CLASS".printf (cl.get_upper_case_cname (null))));
-                       ccast.add_argument (ccall);
-                       cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "klass"), right = ccast)));
+               cdecl = new CCodeDeclaration (type_name = "%sClass *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "klass"));
+               cblock.add_statement (cdecl);
 
-                       ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_peek_parent"));
-                       ccall.add_argument (new CCodeIdentifier (name = "klass"));
-                       ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
-                       ccast.add_argument (ccall);
-                       cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "parent_class"), right = ccast)));
+               cdecl = new CCodeDeclaration (type_name = "GObjectClass *");
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "parent_class"));
+               cblock.add_statement (cdecl);
 
-                       
-                       ccall = new CCodeFunctionCall (call = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "parent_class"), member_name = "constructor", is_pointer = true));
-                       ccall.add_argument (new CCodeIdentifier (name = "type"));
-                       ccall.add_argument (new CCodeIdentifier (name = "n_construct_properties"));
-                       ccall.add_argument (new CCodeIdentifier (name = "construct_properties"));
-                       cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "obj"), right = ccall)));
 
+               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_peek"));
+               ccall.add_argument (new CCodeIdentifier (name = cl.get_upper_case_cname ("TYPE_")));
+               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_CLASS".printf (cl.get_upper_case_cname (null))));
+               ccast.add_argument (ccall);
+               cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "klass"), right = ccast)));
 
-                       ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
-                       ccall.add_argument (new CCodeIdentifier (name = "obj"));
-                       
-                       cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
-                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
-                       
-                       cblock.add_statement (cdecl);
+               ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_type_class_peek_parent"));
+               ccall.add_argument (new CCodeIdentifier (name = "klass"));
+               ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT_CLASS"));
+               ccast.add_argument (ccall);
+               cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "parent_class"), right = ccast)));
 
+               
+               ccall = new CCodeFunctionCall (call = new CCodeMemberAccess (inner = new CCodeIdentifier (name = "parent_class"), member_name = "constructor", is_pointer = true));
+               ccall.add_argument (new CCodeIdentifier (name = "type"));
+               ccall.add_argument (new CCodeIdentifier (name = "n_construct_properties"));
+               ccall.add_argument (new CCodeIdentifier (name = "construct_properties"));
+               cblock.add_statement (new CCodeExpressionStatement (expression = new CCodeAssignment (left = new CCodeIdentifier (name = "obj"), right = ccall)));
 
-                       cblock.add_statement (c.body.ccodenode);
-                       
-                       cblock.add_statement (new CCodeReturnStatement (return_expression = new CCodeIdentifier (name = "obj")));
-                       
-                       function.block = cblock;
 
-                       if (c.source_reference.comment != null) {
-                               source_type_member_definition.append (new CCodeComment (text = c.source_reference.comment));
-                       }
-                       source_type_member_definition.append (function);
-               }
+               ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
+               ccall.add_argument (new CCodeIdentifier (name = "obj"));
+               
+               cdecl = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
+               cdecl.add_declarator (new CCodeVariableDeclarator (name = "self", initializer = ccall));
+               
+               cblock.add_statement (cdecl);
 
-               public override void visit_begin_block (Block! b) {
-                       current_symbol = b.symbol;
+
+               cblock.add_statement (c.body.ccodenode);
+               
+               cblock.add_statement (new CCodeReturnStatement (return_expression = new CCodeIdentifier (name = "obj")));
+               
+               function.block = cblock;
+
+               if (c.source_reference.comment != null) {
+                       source_type_member_definition.append (new CCodeComment (text = c.source_reference.comment));
                }
+               source_type_member_definition.append (function);
+       }
 
-               public override void visit_end_block (Block! b) {
-                       var local_vars = b.get_local_variables ();
-                       foreach (VariableDeclarator decl in local_vars) {
-                               decl.symbol.active = false;
-                       }
+       public override void visit_begin_block (Block! b) {
+               current_symbol = b.symbol;
+       }
+
+       public override void visit_end_block (Block! b) {
+               var local_vars = b.get_local_variables ();
+               foreach (VariableDeclarator decl in local_vars) {
+                       decl.symbol.active = false;
+               }
+       
+               var cblock = new CCodeBlock ();
                
-                       var cblock = new CCodeBlock ();
+               foreach (Statement stmt in b.get_statements ()) {
+                       var src = stmt.source_reference;
+                       if (src != null && src.comment != null) {
+                               cblock.add_statement (new CCodeComment (text = src.comment));
+                       }
                        
-                       foreach (Statement stmt in b.get_statements ()) {
-                               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);
-                                       }
-                               } else {
-                                       cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+                       if (stmt.ccodenode is CCodeFragment) {
+                               foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).children) {
+                                       cblock.add_statement (cstmt);
                                }
+                       } else {
+                               cblock.add_statement ((CCodeStatement) stmt.ccodenode);
                        }
-                       
-                       if (memory_management) {
-                               foreach (VariableDeclarator decl in local_vars) {
-                                       if (decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
-                                               cblock.add_statement (new CCodeExpressionStatement (expression = get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference)));
-                                       }
+               }
+               
+               if (memory_management) {
+                       foreach (VariableDeclarator decl in local_vars) {
+                               if (decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
+                                       cblock.add_statement (new CCodeExpressionStatement (expression = get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference)));
                                }
                        }
-                       
-                       b.ccodenode = cblock;
-
-                       current_symbol = current_symbol.parent_symbol;
                }
+               
+               b.ccodenode = cblock;
 
-               public override void visit_empty_statement (EmptyStatement! stmt) {
-                       stmt.ccodenode = new CCodeEmptyStatement ();
-               }
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_declaration_statement (DeclarationStatement! stmt) {
-                       /* split declaration statement as var declarators
-                        * might have different types */
-               
-                       var cfrag = new CCodeFragment ();
-                       
-                       foreach (VariableDeclarator decl in stmt.declaration.variable_declarators) {
-                               var cdecl = new CCodeDeclaration (type_name = decl.type_reference.get_cname ());
-                       
-                               cdecl.add_declarator ((CCodeVariableDeclarator) decl.ccodenode);
+       public override void visit_empty_statement (EmptyStatement! stmt) {
+               stmt.ccodenode = new CCodeEmptyStatement ();
+       }
 
-                               cfrag.append (cdecl);
-                       }
-                       
-                       stmt.ccodenode = cfrag;
+       public override void visit_declaration_statement (DeclarationStatement! stmt) {
+               /* split declaration statement as var declarators
+                * might have different types */
+       
+               var cfrag = new CCodeFragment ();
+               
+               foreach (VariableDeclarator decl in stmt.declaration.variable_declarators) {
+                       var cdecl = new CCodeDeclaration (type_name = decl.type_reference.get_cname ());
+               
+                       cdecl.add_declarator ((CCodeVariableDeclarator) decl.ccodenode);
 
-                       foreach (VariableDeclarator decl in stmt.declaration.variable_declarators) {
-                               if (decl.initializer != null) {
-                                       create_temp_decl (stmt, decl.initializer.temp_vars);
-                               }
-                       }
+                       cfrag.append (cdecl);
                }
+               
+               stmt.ccodenode = cfrag;
 
-               public override void visit_variable_declarator (VariableDeclarator! decl) {
-                       CCodeExpression rhs = null;
+               foreach (VariableDeclarator decl in stmt.declaration.variable_declarators) {
                        if (decl.initializer != null) {
-                               rhs = (CCodeExpression) decl.initializer.ccodenode;
-                               
-                               if (decl.type_reference.type != null
-                                   && decl.initializer.static_type.type != null
-                                   && decl.type_reference.type.is_reference_type ()
-                                   && decl.initializer.static_type.type != decl.type_reference.type) {
-                                       rhs = new InstanceCast (type_reference = decl.type_reference.type, inner = rhs);
-                               }
-                       } else if (decl.type_reference.type != null && decl.type_reference.type.is_reference_type ()) {
-                               rhs = new CCodeConstant (name = "NULL");
+                               create_temp_decl (stmt, decl.initializer.temp_vars);
                        }
-                               
-                       decl.ccodenode = new CCodeVariableDeclarator (name = decl.name, initializer = rhs);
-
-                       decl.symbol.active = true;
                }
+       }
 
-               public override void visit_initializer_list (InitializerList! list) {
-                       var clist = new CCodeInitializerList ();
-                       foreach (Expression expr in list.initializers) {
-                               clist.append ((CCodeExpression) expr.ccodenode);
+       public override void visit_variable_declarator (VariableDeclarator! decl) {
+               CCodeExpression rhs = null;
+               if (decl.initializer != null) {
+                       rhs = (CCodeExpression) decl.initializer.ccodenode;
+                       
+                       if (decl.type_reference.type != null
+                           && decl.initializer.static_type.type != null
+                           && decl.type_reference.type.is_reference_type ()
+                           && decl.initializer.static_type.type != decl.type_reference.type) {
+                               rhs = new InstanceCast (type_reference = decl.type_reference.type, inner = rhs);
                        }
-                       list.ccodenode = clist;
+               } else if (decl.type_reference.type != null && decl.type_reference.type.is_reference_type ()) {
+                       rhs = new CCodeConstant (name = "NULL");
                }
-               
-               private ref VariableDeclarator get_temp_variable_declarator (TypeReference! type) {
-                       var decl = new VariableDeclarator (name = "__temp%d".printf (next_temp_var_id));
-                       decl.type_reference = type.copy ();
-                       decl.type_reference.is_ref = false;
-                       decl.type_reference.is_out = false;
-                       
-                       next_temp_var_id++;
                        
-                       return decl;
+               decl.ccodenode = new CCodeVariableDeclarator (name = decl.name, initializer = rhs);
+
+               decl.symbol.active = true;
+       }
+
+       public override void visit_initializer_list (InitializerList! list) {
+               var clist = new CCodeInitializerList ();
+               foreach (Expression expr in list.initializers) {
+                       clist.append ((CCodeExpression) expr.ccodenode);
                }
+               list.ccodenode = clist;
+       }
+       
+       private ref VariableDeclarator get_temp_variable_declarator (TypeReference! type) {
+               var decl = new VariableDeclarator (name = "__temp%d".printf (next_temp_var_id));
+               decl.type_reference = type.copy ();
+               decl.type_reference.is_ref = false;
+               decl.type_reference.is_out = false;
                
-               private ref CCodeExpression get_unref_expression (CCodeExpression! cvar, TypeReference! type) {
-                       /* (foo == NULL ? NULL : foo = (unref (foo), NULL)) */
-                       
-                       /* can be simplified to
-                        * foo = (unref (foo), NULL)
-                        * if foo is of static type non-null
-                        */
+               next_temp_var_id++;
+               
+               return decl;
+       }
+       
+       private ref CCodeExpression get_unref_expression (CCodeExpression! cvar, TypeReference! type) {
+               /* (foo == NULL ? NULL : foo = (unref (foo), NULL)) */
+               
+               /* can be simplified to
+                * foo = (unref (foo), NULL)
+                * if foo is of static type non-null
+                */
 
-                       var cisnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = cvar, right = new CCodeConstant (name = "NULL"));
+               var cisnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = cvar, right = new CCodeConstant (name = "NULL"));
 
-                       string unref_function;
-                       if (type.type.is_reference_counting ()) {
-                               unref_function = type.type.get_unref_function ();
-                       } else {
-                               unref_function = type.type.get_free_function ();
-                       }
+               string unref_function;
+               if (type.type.is_reference_counting ()) {
+                       unref_function = type.type.get_unref_function ();
+               } else {
+                       unref_function = type.type.get_free_function ();
+               }
+       
+               if (type.array && type.type.name == "string") {
+                       unref_function = "g_strfreev";
+               }
+               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = unref_function));
+               ccall.add_argument (cvar);
                
-                       if (type.array && type.type.name == "string") {
-                               unref_function = "g_strfreev";
-                       }
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = unref_function));
-                       ccall.add_argument (cvar);
-                       
-                       /* set freed references to NULL to prevent further use */
-                       var ccomma = new CCodeCommaExpression ();
-                       
-                       if (unref_function == "g_list_free") {
-                               bool is_ref = false;
-                               bool is_class = false;
-                               var type_args = type.get_type_arguments ();
-                               foreach (TypeReference type_arg in type_args) {
-                                       is_ref = type_arg.is_ref;
-                                       is_class = type_arg.type is Class;
-                               }
-                               
-                               if (is_ref) {
-                                       var cunrefcall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_list_foreach"));
-                                       cunrefcall.add_argument (cvar);
-                                       if (is_class) {
-                                               cunrefcall.add_argument (new CCodeIdentifier (name = "(GFunc) g_object_unref"));
-                                       } else {
-                                               cunrefcall.add_argument (new CCodeIdentifier (name = "(GFunc) g_free"));
-                                       }
-                                       cunrefcall.add_argument (new CCodeConstant (name = "NULL"));
-                                       ccomma.inner.append (cunrefcall);
+               /* set freed references to NULL to prevent further use */
+               var ccomma = new CCodeCommaExpression ();
+               
+               if (unref_function == "g_list_free") {
+                       bool is_ref = false;
+                       bool is_class = false;
+                       var type_args = type.get_type_arguments ();
+                       foreach (TypeReference type_arg in type_args) {
+                               is_ref = type_arg.is_ref;
+                               is_class = type_arg.type is Class;
+                       }
+                       
+                       if (is_ref) {
+                               var cunrefcall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_list_foreach"));
+                               cunrefcall.add_argument (cvar);
+                               if (is_class) {
+                                       cunrefcall.add_argument (new CCodeIdentifier (name = "(GFunc) g_object_unref"));
+                               } else {
+                                       cunrefcall.add_argument (new CCodeIdentifier (name = "(GFunc) g_free"));
                                }
-                       } else if (unref_function == "g_string_free") {
-                               ccall.add_argument (new CCodeConstant (name = "TRUE"));
+                               cunrefcall.add_argument (new CCodeConstant (name = "NULL"));
+                               ccomma.inner.append (cunrefcall);
                        }
-                       
-                       ccomma.inner.append (ccall);
-                       ccomma.inner.append (new CCodeConstant (name = "NULL"));
-                       
-                       var cassign = new CCodeAssignment (left = cvar, right = ccomma);
-                       
-                       return new CCodeConditionalExpression (condition = cisnull, true_expression = new CCodeConstant (name = "NULL"), false_expression = new CCodeParenthesizedExpression (inner = cassign));
+               } else if (unref_function == "g_string_free") {
+                       ccall.add_argument (new CCodeConstant (name = "TRUE"));
                }
                
-               public override void visit_end_full_expression (Expression! expr) {
-                       if (!memory_management) {
-                               temp_vars = null;
-                               temp_ref_vars = null;
-                               return;
-                       }
+               ccomma.inner.append (ccall);
+               ccomma.inner.append (new CCodeConstant (name = "NULL"));
                
-                       /* expr is a full expression, i.e. an initializer, the
-                        * expression in an expression statement, the controlling
-                        * expression in if, while, for, or foreach statements
-                        *
-                        * we unref temporary variables at the end of a full
-                        * expression
-                        */
-                       
-                       /* can't automatically deep copy lists yet, so do it
-                        * manually for now
-                        * replace with
-                        * expr.temp_vars = temp_vars;
-                        * when deep list copying works
-                        */
-                       expr.temp_vars = null;
-                       foreach (VariableDeclarator decl1 in temp_vars) {
-                               expr.temp_vars.append (decl1);
-                       }
+               var cassign = new CCodeAssignment (left = cvar, right = ccomma);
+               
+               return new CCodeConditionalExpression (condition = cisnull, true_expression = new CCodeConstant (name = "NULL"), false_expression = new CCodeParenthesizedExpression (inner = cassign));
+       }
+       
+       public override void visit_end_full_expression (Expression! expr) {
+               if (!memory_management) {
                        temp_vars = null;
-
-                       if (temp_ref_vars == null) {
-                               /* nothing to do without temporary variables */
-                               return;
-                       }
-                       
-                       var full_expr_decl = get_temp_variable_declarator (expr.static_type);
-                       expr.temp_vars.append (full_expr_decl);
-                       
-                       var expr_list = new CCodeCommaExpression ();
-                       expr_list.inner.append (new CCodeAssignment (left = new CCodeIdentifier (name = full_expr_decl.name), right = expr.ccodenode));
-                       
-                       foreach (VariableDeclarator decl in temp_ref_vars) {
-                               expr_list.inner.append (get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference));
-                       }
-                       
-                       expr_list.inner.append (new CCodeIdentifier (name = full_expr_decl.name));
-                       
-                       expr.ccodenode = expr_list;
-                       
                        temp_ref_vars = null;
+                       return;
+               }
+       
+               /* expr is a full expression, i.e. an initializer, the
+                * expression in an expression statement, the controlling
+                * expression in if, while, for, or foreach statements
+                *
+                * we unref temporary variables at the end of a full
+                * expression
+                */
+               
+               /* can't automatically deep copy lists yet, so do it
+                * manually for now
+                * replace with
+                * expr.temp_vars = temp_vars;
+                * when deep list copying works
+                */
+               expr.temp_vars = null;
+               foreach (VariableDeclarator decl1 in temp_vars) {
+                       expr.temp_vars.append (decl1);
+               }
+               temp_vars = null;
+
+               if (temp_ref_vars == null) {
+                       /* nothing to do without temporary variables */
+                       return;
+               }
+               
+               var full_expr_decl = get_temp_variable_declarator (expr.static_type);
+               expr.temp_vars.append (full_expr_decl);
+               
+               var expr_list = new CCodeCommaExpression ();
+               expr_list.inner.append (new CCodeAssignment (left = new CCodeIdentifier (name = full_expr_decl.name), right = expr.ccodenode));
+               
+               foreach (VariableDeclarator decl in temp_ref_vars) {
+                       expr_list.inner.append (get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference));
                }
                
-               private void append_temp_decl (CCodeFragment! cfrag, List<VariableDeclarator> temp_vars) {
-                       foreach (VariableDeclarator decl in temp_vars) {
-                               var cdecl = new CCodeDeclaration (type_name = decl.type_reference.get_cname (true));
+               expr_list.inner.append (new CCodeIdentifier (name = full_expr_decl.name));
+               
+               expr.ccodenode = expr_list;
+               
+               temp_ref_vars = null;
+       }
+       
+       private void append_temp_decl (CCodeFragment! cfrag, List<VariableDeclarator> temp_vars) {
+               foreach (VariableDeclarator decl in temp_vars) {
+                       var cdecl = new CCodeDeclaration (type_name = decl.type_reference.get_cname (true));
+               
+                       cdecl.add_declarator (new CCodeVariableDeclarator (name = decl.name));
                        
-                               cdecl.add_declarator (new CCodeVariableDeclarator (name = decl.name));
-                               
-                               cfrag.append (cdecl);
-                       }
+                       cfrag.append (cdecl);
                }
+       }
 
-               public override void visit_expression_statement (ExpressionStatement! stmt) {
-                       stmt.ccodenode = new CCodeExpressionStatement (expression = (CCodeExpression) stmt.expression.ccodenode);
-                       
-                       /* free temporary objects */
-                       if (!memory_management) {
-                               temp_vars = null;
-                               temp_ref_vars = null;
-                               return;
-                       }
-                       
-                       if (temp_vars == null) {
-                               /* nothing to do without temporary variables */
-                               return;
-                       }
-                       
-                       var cfrag = new CCodeFragment ();
-                       append_temp_decl (cfrag, temp_vars);
-                       
-                       cfrag.append (stmt.ccodenode);
-                       
-                       foreach (VariableDeclarator decl in temp_ref_vars) {
-                               cfrag.append (new CCodeExpressionStatement (expression = get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference)));
-                       }
-                       
-                       stmt.ccodenode = cfrag;
-                       
+       public override void visit_expression_statement (ExpressionStatement! stmt) {
+               stmt.ccodenode = new CCodeExpressionStatement (expression = (CCodeExpression) stmt.expression.ccodenode);
+               
+               /* free temporary objects */
+               if (!memory_management) {
                        temp_vars = null;
                        temp_ref_vars = null;
+                       return;
                }
                
-               private void create_temp_decl (Statement! stmt, List<VariableDeclarator> temp_vars) {
-                       /* declare temporary variables */
-                       
-                       if (temp_vars == null) {
-                               /* nothing to do without temporary variables */
-                               return;
-                       }
-                       
-                       var cfrag = new CCodeFragment ();
-                       append_temp_decl (cfrag, temp_vars);
-                       
-                       cfrag.append (stmt.ccodenode);
-                       
-                       stmt.ccodenode = cfrag;
+               if (temp_vars == null) {
+                       /* nothing to do without temporary variables */
+                       return;
+               }
+               
+               var cfrag = new CCodeFragment ();
+               append_temp_decl (cfrag, temp_vars);
+               
+               cfrag.append (stmt.ccodenode);
+               
+               foreach (VariableDeclarator decl in temp_ref_vars) {
+                       cfrag.append (new CCodeExpressionStatement (expression = get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference)));
+               }
+               
+               stmt.ccodenode = cfrag;
+               
+               temp_vars = null;
+               temp_ref_vars = null;
+       }
+       
+       private void create_temp_decl (Statement! stmt, List<VariableDeclarator> temp_vars) {
+               /* declare temporary variables */
+               
+               if (temp_vars == null) {
+                       /* nothing to do without temporary variables */
+                       return;
                }
+               
+               var cfrag = new CCodeFragment ();
+               append_temp_decl (cfrag, temp_vars);
+               
+               cfrag.append (stmt.ccodenode);
+               
+               stmt.ccodenode = cfrag;
+       }
 
-               public override void visit_if_statement (IfStatement! stmt) {
-                       if (stmt.false_statement != null) {
-                               stmt.ccodenode = new CCodeIfStatement (condition = (CCodeExpression) stmt.condition.ccodenode, true_statement = (CCodeStatement) stmt.true_statement.ccodenode, false_statement = (CCodeStatement) stmt.false_statement.ccodenode);
-                       } else {
-                               stmt.ccodenode = new CCodeIfStatement (condition = (CCodeExpression) stmt.condition.ccodenode, true_statement = (CCodeStatement) stmt.true_statement.ccodenode);
-                       }
-                       
-                       create_temp_decl (stmt, stmt.condition.temp_vars);
+       public override void visit_if_statement (IfStatement! stmt) {
+               if (stmt.false_statement != null) {
+                       stmt.ccodenode = new CCodeIfStatement (condition = (CCodeExpression) stmt.condition.ccodenode, true_statement = (CCodeStatement) stmt.true_statement.ccodenode, false_statement = (CCodeStatement) stmt.false_statement.ccodenode);
+               } else {
+                       stmt.ccodenode = new CCodeIfStatement (condition = (CCodeExpression) stmt.condition.ccodenode, true_statement = (CCodeStatement) stmt.true_statement.ccodenode);
                }
+               
+               create_temp_decl (stmt, stmt.condition.temp_vars);
+       }
 
-               public override void visit_while_statement (WhileStatement! stmt) {
-                       stmt.ccodenode = new CCodeWhileStatement (condition = (CCodeExpression) stmt.condition.ccodenode, body = (CCodeStatement) stmt.body.ccodenode);
-                       
-                       create_temp_decl (stmt, stmt.condition.temp_vars);
+       public override void visit_while_statement (WhileStatement! stmt) {
+               stmt.ccodenode = new CCodeWhileStatement (condition = (CCodeExpression) stmt.condition.ccodenode, body = (CCodeStatement) stmt.body.ccodenode);
+               
+               create_temp_decl (stmt, stmt.condition.temp_vars);
+       }
+
+       public override void visit_for_statement (ForStatement! stmt) {
+               var cfor = new CCodeForStatement (condition = (CCodeExpression) stmt.condition.ccodenode, body = (CCodeStatement) stmt.body.ccodenode);
+               
+               foreach (Expression init_expr in stmt.initializer) {
+                       cfor.add_initializer ((CCodeExpression) init_expr.ccodenode);
                }
+               
+               foreach (Expression it_expr in stmt.iterator) {
+                       cfor.add_iterator ((CCodeExpression) it_expr.ccodenode);
+               }
+               
+               stmt.ccodenode = cfor;
+               
+               create_temp_decl (stmt, stmt.condition.temp_vars);
+       }
 
-               public override void visit_for_statement (ForStatement! stmt) {
-                       var cfor = new CCodeForStatement (condition = (CCodeExpression) stmt.condition.ccodenode, body = (CCodeStatement) stmt.body.ccodenode);
+       public override void visit_end_foreach_statement (ForeachStatement! stmt) {
+               var cblock = new CCodeBlock ();
+               
+               if (stmt.collection.static_type.array) {
+                       var it_name = "%s_it".printf (stmt.variable_name);
+               
+                       var citdecl = new CCodeDeclaration (type_name = stmt.collection.static_type.get_cname ());
+                       citdecl.add_declarator (new CCodeVariableDeclarator (name = it_name));
+                       cblock.add_statement (citdecl);
                        
-                       foreach (Expression init_expr in stmt.initializer) {
-                               cfor.add_initializer ((CCodeExpression) init_expr.ccodenode);
-                       }
+                       var cbody = new CCodeBlock ();
                        
-                       foreach (Expression it_expr in stmt.iterator) {
-                               cfor.add_iterator ((CCodeExpression) it_expr.ccodenode);
-                       }
+                       var cdecl = new CCodeDeclaration (type_name = stmt.type_reference.get_cname ());
+                       cdecl.add_declarator (new CCodeVariableDeclarator (name = stmt.variable_name, initializer = new CCodeIdentifier (name = "*%s".printf (it_name))));
+                       cbody.add_statement (cdecl);
                        
-                       stmt.ccodenode = cfor;
+                       cbody.add_statement (stmt.body.ccodenode);
                        
-                       create_temp_decl (stmt, stmt.condition.temp_vars);
-               }
-
-               public override void visit_end_foreach_statement (ForeachStatement! stmt) {
-                       var cblock = new CCodeBlock ();
+                       var ccond = new CCodeBinaryExpression (operator = CCodeBinaryOperator.INEQUALITY, left = new CCodeIdentifier (name = "*%s".printf (it_name)), right = new CCodeConstant (name = "NULL"));
                        
-                       if (stmt.collection.static_type.array) {
-                               var it_name = "%s_it".printf (stmt.variable_name);
+                       var cfor = new CCodeForStatement (condition = ccond, body = cbody);
+                       cfor.add_initializer (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = (CCodeExpression) stmt.collection.ccodenode));
+                       cfor.add_iterator (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = new CCodeBinaryExpression (operator = CCodeBinaryOperator.PLUS, left = new CCodeIdentifier (name = it_name), right = new CCodeConstant (name = "1"))));
+                       cblock.add_statement (cfor);
+               } else if (stmt.collection.static_type.type.name == "List") {
+                       var it_name = "%s_it".printf (stmt.variable_name);
+               
+                       var citdecl = new CCodeDeclaration (type_name = "GList *");
+                       citdecl.add_declarator (new CCodeVariableDeclarator (name = it_name));
+                       cblock.add_statement (citdecl);
                        
-                               var citdecl = new CCodeDeclaration (type_name = stmt.collection.static_type.get_cname ());
-                               citdecl.add_declarator (new CCodeVariableDeclarator (name = it_name));
-                               cblock.add_statement (citdecl);
-                               
-                               var cbody = new CCodeBlock ();
-                               
-                               var cdecl = new CCodeDeclaration (type_name = stmt.type_reference.get_cname ());
-                               cdecl.add_declarator (new CCodeVariableDeclarator (name = stmt.variable_name, initializer = new CCodeIdentifier (name = "*%s".printf (it_name))));
-                               cbody.add_statement (cdecl);
-                               
-                               cbody.add_statement (stmt.body.ccodenode);
-                               
-                               var ccond = new CCodeBinaryExpression (operator = CCodeBinaryOperator.INEQUALITY, left = new CCodeIdentifier (name = "*%s".printf (it_name)), right = new CCodeConstant (name = "NULL"));
-                               
-                               var cfor = new CCodeForStatement (condition = ccond, body = cbody);
-                               cfor.add_initializer (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = (CCodeExpression) stmt.collection.ccodenode));
-                               cfor.add_iterator (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = new CCodeBinaryExpression (operator = CCodeBinaryOperator.PLUS, left = new CCodeIdentifier (name = it_name), right = new CCodeConstant (name = "1"))));
-                               cblock.add_statement (cfor);
-                       } else if (stmt.collection.static_type.type.name == "List") {
-                               var it_name = "%s_it".printf (stmt.variable_name);
+                       var cbody = new CCodeBlock ();
                        
-                               var citdecl = new CCodeDeclaration (type_name = "GList *");
-                               citdecl.add_declarator (new CCodeVariableDeclarator (name = it_name));
-                               cblock.add_statement (citdecl);
-                               
-                               var cbody = new CCodeBlock ();
-                               
-                               var cdecl = new CCodeDeclaration (type_name = stmt.type_reference.get_cname ());
-                               cdecl.add_declarator (new CCodeVariableDeclarator (name = stmt.variable_name, initializer = new CCodeMemberAccess (inner = new CCodeIdentifier (name = it_name), member_name = "data", is_pointer = true)));
-                               cbody.add_statement (cdecl);
-                               
-                               cbody.add_statement (stmt.body.ccodenode);
-                               
-                               var ccond = new CCodeBinaryExpression (operator = CCodeBinaryOperator.INEQUALITY, left = new CCodeIdentifier (name = it_name), right = new CCodeConstant (name = "NULL"));
-                               
-                               var cfor = new CCodeForStatement (condition = ccond, body = cbody);
-                               cfor.add_initializer (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = (CCodeExpression) stmt.collection.ccodenode));
-                               cfor.add_iterator (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = new CCodeMemberAccess (inner = new CCodeIdentifier (name = it_name), member_name = "next", is_pointer = true)));
-                               cblock.add_statement (cfor);
-                       }
+                       var cdecl = new CCodeDeclaration (type_name = stmt.type_reference.get_cname ());
+                       cdecl.add_declarator (new CCodeVariableDeclarator (name = stmt.variable_name, initializer = new CCodeMemberAccess (inner = new CCodeIdentifier (name = it_name), member_name = "data", is_pointer = true)));
+                       cbody.add_statement (cdecl);
                        
-                       stmt.ccodenode = cblock;
-               }
-
-               public override void visit_break_statement (BreakStatement! stmt) {
-                       stmt.ccodenode = new CCodeBreakStatement ();
-               }
-
-               public override void visit_continue_statement (ContinueStatement! stmt) {
-                       stmt.ccodenode = new CCodeContinueStatement ();
-               }
-               
-               private void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop) {
-                       var b = (Block) sym.node;
-
-                       var local_vars = b.get_local_variables ();
-                       foreach (VariableDeclarator decl in local_vars) {
-                               if (decl.symbol.active && decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
-                                       cfrag.append (new CCodeExpressionStatement (expression = get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference)));
-                               }
-                       }
+                       cbody.add_statement (stmt.body.ccodenode);
                        
-                       if (sym.parent_symbol.node is Block) {
-                               append_local_free (sym.parent_symbol, cfrag, stop_at_loop);
-                       }
-               }
-
-               private void create_local_free (Statement stmt) {
-                       if (!memory_management) {
-                               return;
-                       }
+                       var ccond = new CCodeBinaryExpression (operator = CCodeBinaryOperator.INEQUALITY, left = new CCodeIdentifier (name = it_name), right = new CCodeConstant (name = "NULL"));
                        
-                       var cfrag = new CCodeFragment ();
-               
-                       append_local_free (current_symbol, cfrag, false);
-
-                       cfrag.append (stmt.ccodenode);
-                       stmt.ccodenode = cfrag;
+                       var cfor = new CCodeForStatement (condition = ccond, body = cbody);
+                       cfor.add_initializer (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = (CCodeExpression) stmt.collection.ccodenode));
+                       cfor.add_iterator (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = new CCodeMemberAccess (inner = new CCodeIdentifier (name = it_name), member_name = "next", is_pointer = true)));
+                       cblock.add_statement (cfor);
                }
                
-               private bool append_local_free_expr (Symbol sym, CCodeCommaExpression ccomma, bool stop_at_loop) {
-                       var found = false;
-               
-                       var b = (Block) sym.node;
+               stmt.ccodenode = cblock;
+       }
 
-                       var local_vars = b.get_local_variables ();
-                       foreach (VariableDeclarator decl in local_vars) {
-                               if (decl.symbol.active && decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
-                                       found = true;
-                                       ccomma.inner.append (get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference));
-                               }
-                       }
-                       
-                       if (sym.parent_symbol.node is Block) {
-                               found = found || append_local_free_expr (sym.parent_symbol, ccomma, stop_at_loop);
-                       }
-                       
-                       return found;
-               }
+       public override void visit_break_statement (BreakStatement! stmt) {
+               stmt.ccodenode = new CCodeBreakStatement ();
+       }
 
-               private void create_local_free_expr (Expression expr) {
-                       if (!memory_management) {
-                               return;
-                       }
-                       
-                       var return_expr_decl = get_temp_variable_declarator (expr.static_type);
-                       
-                       var ccomma = new CCodeCommaExpression ();
-                       ccomma.inner.append (new CCodeAssignment (left = new CCodeIdentifier (name = return_expr_decl.name), right = expr.ccodenode));
+       public override void visit_continue_statement (ContinueStatement! stmt) {
+               stmt.ccodenode = new CCodeContinueStatement ();
+       }
+       
+       private void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop) {
+               var b = (Block) sym.node;
 
-                       if (!append_local_free_expr (current_symbol, ccomma, false)) {
-                               /* no local variables need to be freed */
-                               return;
+               var local_vars = b.get_local_variables ();
+               foreach (VariableDeclarator decl in local_vars) {
+                       if (decl.symbol.active && decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
+                               cfrag.append (new CCodeExpressionStatement (expression = get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference)));
                        }
+               }
+               
+               if (sym.parent_symbol.node is Block) {
+                       append_local_free (sym.parent_symbol, cfrag, stop_at_loop);
+               }
+       }
 
-                       ccomma.inner.append (new CCodeIdentifier (name = return_expr_decl.name));
-                       
-                       expr.ccodenode = ccomma;
-                       expr.temp_vars.append (return_expr_decl);
+       private void create_local_free (Statement stmt) {
+               if (!memory_management) {
+                       return;
                }
+               
+               var cfrag = new CCodeFragment ();
+       
+               append_local_free (current_symbol, cfrag, false);
 
-               public override void visit_return_statement (ReturnStatement! stmt) {
-                       if (stmt.return_expression == null) {
-                               stmt.ccodenode = new CCodeReturnStatement ();
-                               
-                               create_local_free (stmt);
-                       } else {
-                               create_local_free_expr (stmt.return_expression);
+               cfrag.append (stmt.ccodenode);
+               stmt.ccodenode = cfrag;
+       }
+       
+       private bool append_local_free_expr (Symbol sym, CCodeCommaExpression ccomma, bool stop_at_loop) {
+               var found = false;
+       
+               var b = (Block) sym.node;
 
-                               stmt.ccodenode = new CCodeReturnStatement (return_expression = (CCodeExpression) stmt.return_expression.ccodenode);
-                       
-                               create_temp_decl (stmt, stmt.return_expression.temp_vars);
+               var local_vars = b.get_local_variables ();
+               foreach (VariableDeclarator decl in local_vars) {
+                       if (decl.symbol.active && decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
+                               found = true;
+                               ccomma.inner.append (get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference));
                        }
                }
-
-               public override void visit_boolean_literal (BooleanLiteral! expr) {
-                       if (expr.value) {
-                               expr.ccodenode = new CCodeConstant (name = "TRUE");
-                       } else {
-                               expr.ccodenode = new CCodeConstant (name = "FALSE");
-                       }
+               
+               if (sym.parent_symbol.node is Block) {
+                       found = found || append_local_free_expr (sym.parent_symbol, ccomma, stop_at_loop);
                }
+               
+               return found;
+       }
 
-               public override void visit_character_literal (CharacterLiteral! expr) {
-                       expr.ccodenode = new CCodeConstant (name = expr.value);
+       private void create_local_free_expr (Expression expr) {
+               if (!memory_management) {
+                       return;
                }
+               
+               var return_expr_decl = get_temp_variable_declarator (expr.static_type);
+               
+               var ccomma = new CCodeCommaExpression ();
+               ccomma.inner.append (new CCodeAssignment (left = new CCodeIdentifier (name = return_expr_decl.name), right = expr.ccodenode));
 
-               public override void visit_integer_literal (IntegerLiteral! expr) {
-                       expr.ccodenode = new CCodeConstant (name = expr.value);
+               if (!append_local_free_expr (current_symbol, ccomma, false)) {
+                       /* no local variables need to be freed */
+                       return;
                }
 
-               public override void visit_real_literal (RealLiteral! expr) {
-                       expr.ccodenode = new CCodeConstant (name = expr.value);
-               }
+               ccomma.inner.append (new CCodeIdentifier (name = return_expr_decl.name));
+               
+               expr.ccodenode = ccomma;
+               expr.temp_vars.append (return_expr_decl);
+       }
 
-               public override void visit_string_literal (StringLiteral! expr) {
-                       expr.ccodenode = new CCodeConstant (name = expr.value);
-               }
+       public override void visit_return_statement (ReturnStatement! stmt) {
+               if (stmt.return_expression == null) {
+                       stmt.ccodenode = new CCodeReturnStatement ();
+                       
+                       create_local_free (stmt);
+               } else {
+                       create_local_free_expr (stmt.return_expression);
 
-               public override void visit_null_literal (NullLiteral! expr) {
-                       expr.ccodenode = new CCodeConstant (name = "NULL");
+                       stmt.ccodenode = new CCodeReturnStatement (return_expression = (CCodeExpression) stmt.return_expression.ccodenode);
+               
+                       create_temp_decl (stmt, stmt.return_expression.temp_vars);
                }
+       }
 
-               public override void visit_literal_expression (LiteralExpression! expr) {
-                       expr.ccodenode = expr.literal.ccodenode;
-                       
-                       visit_expression (expr);
+       public override void visit_boolean_literal (BooleanLiteral! expr) {
+               if (expr.value) {
+                       expr.ccodenode = new CCodeConstant (name = "TRUE");
+               } else {
+                       expr.ccodenode = new CCodeConstant (name = "FALSE");
                }
+       }
+
+       public override void visit_character_literal (CharacterLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (name = expr.value);
+       }
+
+       public override void visit_integer_literal (IntegerLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (name = expr.value);
+       }
+
+       public override void visit_real_literal (RealLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (name = expr.value);
+       }
+
+       public override void visit_string_literal (StringLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (name = expr.value);
+       }
+
+       public override void visit_null_literal (NullLiteral! expr) {
+               expr.ccodenode = new CCodeConstant (name = "NULL");
+       }
+
+       public override void visit_literal_expression (LiteralExpression! expr) {
+               expr.ccodenode = expr.literal.ccodenode;
                
-               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) {
-                                       expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
+               visit_expression (expr);
+       }
+       
+       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) {
+                               expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
+                       } else {
+                               expr.ccodenode = new CCodeIdentifier (name = m.base_method.get_cname ());
+                       }
+               } else if (expr.symbol_reference.node is Field) {
+                       var f = (Field) expr.symbol_reference.node;
+                       if (f.instance) {
+                               ref CCodeExpression typed_inst;
+                               if (f.symbol.parent_symbol.node != base_type) {
+                                       typed_inst = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) f.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                                       ((CCodeFunctionCall) typed_inst).add_argument (pub_inst);
                                } else {
-                                       expr.ccodenode = new CCodeIdentifier (name = m.base_method.get_cname ());
+                                       typed_inst = pub_inst;
                                }
-                       } else if (expr.symbol_reference.node is Field) {
-                               var f = (Field) expr.symbol_reference.node;
-                               if (f.instance) {
-                                       ref CCodeExpression typed_inst;
-                                       if (f.symbol.parent_symbol.node != base_type) {
-                                               typed_inst = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) f.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                                               ((CCodeFunctionCall) typed_inst).add_argument (pub_inst);
-                                       } else {
-                                               typed_inst = pub_inst;
-                                       }
-                                       ref CCodeExpression inst;
-                                       if (f.access == MemberAccessibility.PRIVATE) {
-                                               inst = new CCodeMemberAccess (inner = typed_inst, member_name = "priv", is_pointer = true);
-                                       } else {
-                                               inst = typed_inst;
-                                       }
-                                       expr.ccodenode = new CCodeMemberAccess (inner = inst, member_name = f.get_cname (), is_pointer = true);
+                               ref CCodeExpression inst;
+                               if (f.access == MemberAccessibility.PRIVATE) {
+                                       inst = new CCodeMemberAccess (inner = typed_inst, member_name = "priv", is_pointer = true);
                                } else {
-                                       if (f.symbol.parent_symbol.node is DataType) {
-                                               var t = (DataType) f.symbol.parent_symbol.node;
-                                               expr.ccodenode = new CCodeIdentifier (name = "%s_%s".printf (t.get_lower_case_cname (null), f.get_cname ()));
-                                       } else {
-                                               expr.ccodenode = new CCodeIdentifier (name = f.get_cname ());
-                                       }
+                                       inst = typed_inst;
                                }
-                       } else if (expr.symbol_reference.node is Constant) {
-                               var c = (Constant) expr.symbol_reference.node;
-                               expr.ccodenode = new CCodeIdentifier (name = c.get_cname ());
-                       } else if (expr.symbol_reference.node is Property) {
-                               var prop = (Property) expr.symbol_reference.node;
-                               var cl = (Class) prop.symbol.parent_symbol.node;
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name)));
-                               
-                               /* explicitly use strong reference as ccast
-                                * gets unrefed at the end of the inner block
-                                */
-                               ref CCodeExpression typed_pub_inst = pub_inst;
-
-                               /* cast if necessary */
-                               if (prop.no_accessor_method) {
-                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT"));
-                                       ccast.add_argument (pub_inst);
-                                       typed_pub_inst = ccast;
-                               } else if (prop.symbol.parent_symbol.node != base_type) {
-                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                                       ccast.add_argument (pub_inst);
-                                       typed_pub_inst = ccast;
+                               expr.ccodenode = new CCodeMemberAccess (inner = inst, member_name = f.get_cname (), is_pointer = true);
+                       } else {
+                               if (f.symbol.parent_symbol.node is DataType) {
+                                       var t = (DataType) f.symbol.parent_symbol.node;
+                                       expr.ccodenode = new CCodeIdentifier (name = "%s_%s".printf (t.get_lower_case_cname (null), f.get_cname ()));
+                               } else {
+                                       expr.ccodenode = new CCodeIdentifier (name = f.get_cname ());
                                }
+                       }
+               } else if (expr.symbol_reference.node is Constant) {
+                       var c = (Constant) expr.symbol_reference.node;
+                       expr.ccodenode = new CCodeIdentifier (name = c.get_cname ());
+               } else if (expr.symbol_reference.node is Property) {
+                       var prop = (Property) expr.symbol_reference.node;
+                       var cl = (Class) prop.symbol.parent_symbol.node;
+                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name)));
+                       
+                       /* explicitly use strong reference as ccast
+                        * gets unrefed at the end of the inner block
+                        */
+                       ref CCodeExpression typed_pub_inst = pub_inst;
+
+                       /* cast if necessary */
+                       if (prop.no_accessor_method) {
+                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT"));
+                               ccast.add_argument (pub_inst);
+                               typed_pub_inst = ccast;
+                       } else if (prop.symbol.parent_symbol.node != base_type) {
+                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                               ccast.add_argument (pub_inst);
+                               typed_pub_inst = ccast;
+                       }
 
-                               ccall.add_argument (typed_pub_inst);
-                               expr.ccodenode = ccall;
-                       } else if (expr.symbol_reference.node is EnumValue) {
-                               var ev = (EnumValue) expr.symbol_reference.node;
-                               expr.ccodenode = new CCodeConstant (name = ev.get_cname ());
-                       } else if (expr.symbol_reference.node is VariableDeclarator) {
-                               var decl = (VariableDeclarator) expr.symbol_reference.node;
-                               expr.ccodenode = new CCodeIdentifier (name = decl.name);
-                       } else if (expr.symbol_reference.node is FormalParameter) {
-                               var p = (FormalParameter) expr.symbol_reference.node;
-                               if (p.name == "this") {
-                                       expr.ccodenode = pub_inst;
+                       ccall.add_argument (typed_pub_inst);
+                       expr.ccodenode = ccall;
+               } else if (expr.symbol_reference.node is EnumValue) {
+                       var ev = (EnumValue) expr.symbol_reference.node;
+                       expr.ccodenode = new CCodeConstant (name = ev.get_cname ());
+               } else if (expr.symbol_reference.node is VariableDeclarator) {
+                       var decl = (VariableDeclarator) expr.symbol_reference.node;
+                       expr.ccodenode = new CCodeIdentifier (name = decl.name);
+               } else if (expr.symbol_reference.node is FormalParameter) {
+                       var p = (FormalParameter) expr.symbol_reference.node;
+                       if (p.name == "this") {
+                               expr.ccodenode = pub_inst;
+                       } else {
+                               if (p.type_reference.is_out || p.type_reference.is_ref) {
+                                       expr.ccodenode = new CCodeIdentifier (name = "*%s".printf (p.name));
                                } else {
-                                       if (p.type_reference.is_out || p.type_reference.is_ref) {
-                                               expr.ccodenode = new CCodeIdentifier (name = "*%s".printf (p.name));
-                                       } else {
-                                               expr.ccodenode = new CCodeIdentifier (name = p.name);
-                                       }
+                                       expr.ccodenode = new CCodeIdentifier (name = p.name);
                                }
                        }
                }
-               
-               public override void visit_parenthesized_expression (ParenthesizedExpression! expr) {
-                       expr.ccodenode = new CCodeParenthesizedExpression (inner = (CCodeExpression) expr.inner.ccodenode);
+       }
+       
+       public override void visit_parenthesized_expression (ParenthesizedExpression! expr) {
+               expr.ccodenode = new CCodeParenthesizedExpression (inner = (CCodeExpression) expr.inner.ccodenode);
 
-                       visit_expression (expr);
-               }
+               visit_expression (expr);
+       }
 
-               public override void visit_member_access (MemberAccess! expr) {
-                       CCodeExpression pub_inst = null;
-                       DataType base_type = null;
-               
-                       if (expr.inner == null) {
-                               pub_inst = new CCodeIdentifier (name = "self");
+       public override void visit_member_access (MemberAccess! expr) {
+               CCodeExpression pub_inst = null;
+               DataType base_type = null;
+       
+               if (expr.inner == null) {
+                       pub_inst = new CCodeIdentifier (name = "self");
 
-                               if (current_type_symbol != null) {
-                                       /* base type is available if this is a type method */
-                                       base_type = (DataType) current_type_symbol.node;
-                               }
-                       } else {
-                               pub_inst = (CCodeExpression) expr.inner.ccodenode;
+                       if (current_type_symbol != null) {
+                               /* base type is available if this is a type method */
+                               base_type = (DataType) current_type_symbol.node;
+                       }
+               } else {
+                       pub_inst = (CCodeExpression) expr.inner.ccodenode;
 
-                               if (expr.inner.static_type != null) {
-                                       base_type = expr.inner.static_type.type;
-                               }
+                       if (expr.inner.static_type != null) {
+                               base_type = expr.inner.static_type.type;
                        }
+               }
 
-                       process_cmember (expr, pub_inst, base_type);
+               process_cmember (expr, pub_inst, base_type);
 
-                       visit_expression (expr);
-               }
+               visit_expression (expr);
+       }
 
-               public override void visit_end_invocation_expression (InvocationExpression! expr) {
-                       var ccall = new CCodeFunctionCall (call = (CCodeExpression) expr.call.ccodenode);
-                       
-                       Method m = null;
-                       List<FormalParameter> params;
-                       
-                       if (!(expr.call is MemberAccess)) {
-                               expr.error = true;
-                               Report.error (expr.source_reference, "unsupported method invocation");
-                               return;
-                       }
-                       
-                       var ma = (MemberAccess) expr.call;
-                       
-                       if (expr.call.symbol_reference.node is VariableDeclarator) {
-                               var decl = (VariableDeclarator) expr.call.symbol_reference.node;
-                               var cb = (Callback) decl.type_reference.type;
-                               params = cb.get_parameters ();
-                       } else if (expr.call.symbol_reference.node is FormalParameter) {
-                               var param = (FormalParameter) expr.call.symbol_reference.node;
-                               var cb = (Callback) param.type_reference.type;
-                               params = cb.get_parameters ();
+       public override void visit_end_invocation_expression (InvocationExpression! expr) {
+               var ccall = new CCodeFunctionCall (call = (CCodeExpression) expr.call.ccodenode);
+               
+               Method m = null;
+               List<FormalParameter> params;
+               
+               if (!(expr.call is MemberAccess)) {
+                       expr.error = true;
+                       Report.error (expr.source_reference, "unsupported method invocation");
+                       return;
+               }
+               
+               var ma = (MemberAccess) expr.call;
+               
+               if (expr.call.symbol_reference.node is VariableDeclarator) {
+                       var decl = (VariableDeclarator) expr.call.symbol_reference.node;
+                       var cb = (Callback) decl.type_reference.type;
+                       params = cb.get_parameters ();
+               } else if (expr.call.symbol_reference.node is FormalParameter) {
+                       var param = (FormalParameter) expr.call.symbol_reference.node;
+                       var cb = (Callback) param.type_reference.type;
+                       params = cb.get_parameters ();
+               } else {
+                       m = (Method) expr.call.symbol_reference.node;
+                       params = m.get_parameters ();
+               }
+               
+               /* explicitly use strong reference as ccall gets unrefed
+                * at end of inner block
+                */
+               ref CCodeExpression instance;
+               if (m != null && m.instance) {
+                       var base_method = m;
+                       if (m.is_override) {
+                               base_method = m.base_method;
+                       }
+
+                       var req_cast = false;
+                       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);
                        } else {
-                               m = (Method) expr.call.symbol_reference.node;
-                               params = m.get_parameters ();
+                               instance = (CCodeExpression) ma.inner.ccodenode;
+                               /* reqiure casts if the type of the used instance is
+                                * different than the type which declared the method */
+                               req_cast = base_method.symbol.parent_symbol.node != ma.inner.static_type.type;
                        }
                        
-                       /* explicitly use strong reference as ccall gets unrefed
-                        * at end of inner block
-                        */
-                       ref CCodeExpression instance;
-                       if (m != null && m.instance) {
-                               var base_method = m;
-                               if (m.is_override) {
-                                       base_method = m.base_method;
-                               }
-
-                               var req_cast = false;
-                               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);
-                               } else {
-                                       instance = (CCodeExpression) ma.inner.ccodenode;
-                                       /* reqiure casts if the type of the used instance is
-                                        * different than the type which declared the method */
-                                       req_cast = base_method.symbol.parent_symbol.node != ma.inner.static_type.type;
-                               }
-                               
-                               if (req_cast && ((DataType) m.symbol.parent_symbol.node).is_reference_type ()) {
-                                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) base_method.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                                       ccall.add_argument (instance);
-                                       instance = ccall;
-                               }
-                               
-                               if (!m.instance_last) {
-                                       ccall.add_argument (instance);
-                               }
+                       if (req_cast && ((DataType) m.symbol.parent_symbol.node).is_reference_type ()) {
+                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) base_method.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                               ccall.add_argument (instance);
+                               instance = ccall;
                        }
                        
-                       var i = 1;
-                       foreach (Expression arg in expr.argument_list) {
-                               /* explicitly use strong reference as ccall gets
-                                * unrefed at end of inner block
-                                */
-                               ref CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
-                               if (params != null) {
-                                       var param = (FormalParameter) params.data;
-                                       if (!param.ellipsis
-                                           && param.type_reference.type != null
-                                           && param.type_reference.type.is_reference_type ()
-                                           && arg.static_type.type != null
-                                           && param.type_reference.type != arg.static_type.type) {
-                                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = param.type_reference.type.get_upper_case_cname (null)));
-                                               ccall.add_argument (cexpr);
-                                               cexpr = ccall;
-                                       }
-                               }
-                       
-                               ccall.add_argument (cexpr);
-                               i++;
-                               
-                               if (params != null) {
-                                       params = params.next;
-                               }
+                       if (!m.instance_last) {
+                               ccall.add_argument (instance);
                        }
-                       while (params != null) {
+               }
+               
+               var i = 1;
+               foreach (Expression arg in expr.argument_list) {
+                       /* explicitly use strong reference as ccall gets
+                        * unrefed at end of inner block
+                        */
+                       ref CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
+                       if (params != null) {
                                var param = (FormalParameter) params.data;
-                               
-                               if (param.ellipsis) {
-                                       break;
-                               }
-                               
-                               if (param.default_expression == null) {
-                                       Report.error (expr.source_reference, "no default expression for argument %d".printf (i));
-                                       return;
+                               if (!param.ellipsis
+                                   && param.type_reference.type != null
+                                   && param.type_reference.type.is_reference_type ()
+                                   && arg.static_type.type != null
+                                   && param.type_reference.type != arg.static_type.type) {
+                                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = param.type_reference.type.get_upper_case_cname (null)));
+                                       ccall.add_argument (cexpr);
+                                       cexpr = ccall;
                                }
-                               
-                               /* evaluate default expression here as the code
-                                * generator might not have visited the formal
-                                * parameter yet */
-                               param.default_expression.accept (this);
-                       
-                               ccall.add_argument ((CCodeExpression) param.default_expression.ccodenode);
-                               i++;
+                       }
+               
+                       ccall.add_argument (cexpr);
+                       i++;
                        
+                       if (params != null) {
                                params = params.next;
                        }
+               }
+               while (params != null) {
+                       var param = (FormalParameter) params.data;
                        
-                       if (m != null && m.instance && m.instance_last) {
-                               ccall.add_argument (instance);
+                       if (param.ellipsis) {
+                               break;
                        }
                        
-                       if (m != null && m.instance && m.returns_modified_pointer) {
-                               expr.ccodenode = new CCodeAssignment (left = instance, right = ccall);
-                       } else {
-                               expr.ccodenode = ccall;
-                       
-                               visit_expression (expr);
-                       }
-               }
-
-               public override void visit_postfix_expression (PostfixExpression! expr) {
-                       if (expr.increment) {
-                               expr.ccodenode = new CCodeUnaryExpression (operator = CCodeUnaryOperator.POSTFIX_INCREMENT, inner = expr.inner.ccodenode);
-                       } else {
-                               expr.ccodenode = new CCodeUnaryExpression (operator = CCodeUnaryOperator.POSTFIX_DECREMENT, inner = expr.inner.ccodenode);
+                       if (param.default_expression == null) {
+                               Report.error (expr.source_reference, "no default expression for argument %d".printf (i));
+                               return;
                        }
                        
-                       visit_expression (expr);
-               }
+                       /* evaluate default expression here as the code
+                        * generator might not have visited the formal
+                        * parameter yet */
+                       param.default_expression.accept (this);
                
-               private ref CCodeExpression get_ref_expression (Expression! expr) {
-                       /* (temp = expr, temp == NULL ? temp : ref (temp))
-                        *
-                        * can be simplified to
-                        * ref (expr)
-                        * if static type of expr is non-null
-                        *
-                        * can be simplified to
-                        * (expr == NULL ? expr : ref (expr))
-                        * if expr.ccodenode is CCodeSimpleName or CCodeMemberAccess
-                        */
-               
-                       var decl = get_temp_variable_declarator (expr.static_type);
-                       temp_vars.prepend (decl);
-
-                       var ctemp = new CCodeIdentifier (name = decl.name);
-                       
-                       var cisnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = ctemp, right = new CCodeConstant (name = "NULL"));
-                       
-                       string ref_function;
-                       if (expr.static_type.type.is_reference_counting ()) {
-                               ref_function = expr.static_type.type.get_ref_function ();
-                       } else {
-                               ref_function = expr.static_type.type.get_dup_function ();
-                       }
+                       ccall.add_argument ((CCodeExpression) param.default_expression.ccodenode);
+                       i++;
                
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = ref_function));
-                       ccall.add_argument (ctemp);
-                       
-                       var ccomma = new CCodeCommaExpression ();
-                       ccomma.inner.append (new CCodeAssignment (left = ctemp, right = expr.ccodenode));
-                       ccomma.inner.append (new CCodeConditionalExpression (condition = cisnull, true_expression = ctemp, false_expression = ccall));
-
-                       return ccomma;
-               }
-               
-               private void visit_expression (Expression! expr) {
-                       if (expr.static_type != null &&
-                           expr.static_type.is_ref &&
-                           expr.static_type.floating_reference) {
-                               /* constructor of GInitiallyUnowned subtype
-                                * returns floating reference, sink it
-                                */
-                               var csink = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_ref_sink"));
-                               csink.add_argument ((CCodeExpression) expr.ccodenode);
-                               
-                               expr.ccodenode = csink;
-                       }
+                       params = params.next;
+               }
                
-                       if (expr.ref_leaked) {
-                               var decl = get_temp_variable_declarator (expr.static_type);
-                               temp_vars.prepend (decl);
-                               temp_ref_vars.prepend (decl);
-                               expr.ccodenode = new CCodeParenthesizedExpression (inner = new CCodeAssignment (left = new CCodeIdentifier (name = decl.name), right = expr.ccodenode));
-                       } else if (expr.ref_missing) {
-                               expr.ccodenode = get_ref_expression (expr);
-                       }
+               if (m != null && m.instance && m.instance_last) {
+                       ccall.add_argument (instance);
                }
-
-               public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_new"));
-                       
-                       ccall.add_argument (new CCodeConstant (name = expr.type_reference.get_upper_case_cname ("TYPE_")));
-
-                       foreach (NamedArgument arg in expr.named_argument_list) {
-                               ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (arg.name)));
-                               ccall.add_argument ((CCodeExpression) arg.argument.ccodenode);
-                       }
-                       ccall.add_argument (new CCodeConstant (name = "NULL"));
-                       
+               
+               if (m != null && m.instance && m.returns_modified_pointer) {
+                       expr.ccodenode = new CCodeAssignment (left = instance, right = ccall);
+               } else {
                        expr.ccodenode = ccall;
-                       
+               
                        visit_expression (expr);
                }
+       }
 
-               public override void visit_typeof_expression (TypeofExpression! expr) {
-                       expr.ccodenode = new CCodeIdentifier (name = expr.type_reference.type.get_type_id ());
-               }
-
-               public override void visit_unary_expression (UnaryExpression! expr) {
-                       CCodeUnaryOperator op;
-                       if (expr.operator == UnaryOperator.PLUS) {
-                               op = CCodeUnaryOperator.PLUS;
-                       } else if (expr.operator == UnaryOperator.MINUS) {
-                               op = CCodeUnaryOperator.MINUS;
-                       } else if (expr.operator == UnaryOperator.LOGICAL_NEGATION) {
-                               op = CCodeUnaryOperator.LOGICAL_NEGATION;
-                       } else if (expr.operator == UnaryOperator.BITWISE_COMPLEMENT) {
-                               op = CCodeUnaryOperator.BITWISE_COMPLEMENT;
-                       } else if (expr.operator == UnaryOperator.REF) {
-                               op = CCodeUnaryOperator.ADDRESS_OF;
-                       } else if (expr.operator == UnaryOperator.OUT) {
-                               op = CCodeUnaryOperator.ADDRESS_OF;
-                       }
-                       expr.ccodenode = new CCodeUnaryExpression (operator = op, inner = expr.inner.ccodenode);
-                       
-                       visit_expression (expr);
+       public override void visit_postfix_expression (PostfixExpression! expr) {
+               if (expr.increment) {
+                       expr.ccodenode = new CCodeUnaryExpression (operator = CCodeUnaryOperator.POSTFIX_INCREMENT, inner = expr.inner.ccodenode);
+               } else {
+                       expr.ccodenode = new CCodeUnaryExpression (operator = CCodeUnaryOperator.POSTFIX_DECREMENT, inner = expr.inner.ccodenode);
                }
+               
+               visit_expression (expr);
+       }
+       
+       private ref CCodeExpression get_ref_expression (Expression! expr) {
+               /* (temp = expr, temp == NULL ? temp : ref (temp))
+                *
+                * can be simplified to
+                * ref (expr)
+                * if static type of expr is non-null
+                *
+                * can be simplified to
+                * (expr == NULL ? expr : ref (expr))
+                * if expr.ccodenode is CCodeSimpleName or CCodeMemberAccess
+                */
+       
+               var decl = get_temp_variable_declarator (expr.static_type);
+               temp_vars.prepend (decl);
 
-               public override void visit_cast_expression (CastExpression! expr) {
-                       if (expr.type_reference.type is Struct || expr.type_reference.type is Enum || expr.type_reference.type is Flags) {
-                               expr.ccodenode = expr.inner.ccodenode;
-                       } else {
-                               expr.ccodenode = new InstanceCast (type_reference = expr.type_reference.type, inner = (CCodeExpression) expr.inner.ccodenode);
-                       }
-                       
-                       visit_expression (expr);
+               var ctemp = new CCodeIdentifier (name = decl.name);
+               
+               var cisnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = ctemp, right = new CCodeConstant (name = "NULL"));
+               
+               string ref_function;
+               if (expr.static_type.type.is_reference_counting ()) {
+                       ref_function = expr.static_type.type.get_ref_function ();
+               } else {
+                       ref_function = expr.static_type.type.get_dup_function ();
                }
+       
+               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = ref_function));
+               ccall.add_argument (ctemp);
+               
+               var ccomma = new CCodeCommaExpression ();
+               ccomma.inner.append (new CCodeAssignment (left = ctemp, right = expr.ccodenode));
+               ccomma.inner.append (new CCodeConditionalExpression (condition = cisnull, true_expression = ctemp, false_expression = ccall));
 
-               public override void visit_binary_expression (BinaryExpression! expr) {
-                       expr.ccodenode = new CCodeBinaryExpression (operator = expr.operator, left = expr.left.ccodenode, right = expr.right.ccodenode);
+               return ccomma;
+       }
+       
+       private void visit_expression (Expression! expr) {
+               if (expr.static_type != null &&
+                   expr.static_type.is_ref &&
+                   expr.static_type.floating_reference) {
+                       /* constructor of GInitiallyUnowned subtype
+                        * returns floating reference, sink it
+                        */
+                       var csink = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_ref_sink"));
+                       csink.add_argument ((CCodeExpression) expr.ccodenode);
                        
-                       visit_expression (expr);
+                       expr.ccodenode = csink;
                }
-
-               public override void visit_type_check (TypeCheck! expr) {
-                       var ccheck = new CCodeFunctionCall (call = new CCodeIdentifier (name = expr.type_reference.type.get_upper_case_cname ("IS_")));
-                       ccheck.add_argument ((CCodeExpression) expr.expression.ccodenode);
-                       expr.ccodenode = ccheck;
+       
+               if (expr.ref_leaked) {
+                       var decl = get_temp_variable_declarator (expr.static_type);
+                       temp_vars.prepend (decl);
+                       temp_ref_vars.prepend (decl);
+                       expr.ccodenode = new CCodeParenthesizedExpression (inner = new CCodeAssignment (left = new CCodeIdentifier (name = decl.name), right = expr.ccodenode));
+               } else if (expr.ref_missing) {
+                       expr.ccodenode = get_ref_expression (expr);
                }
+       }
+
+       public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
+               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_new"));
+               
+               ccall.add_argument (new CCodeConstant (name = expr.type_reference.get_upper_case_cname ("TYPE_")));
 
-               public override void visit_conditional_expression (ConditionalExpression! expr) {
-                       expr.ccodenode = new CCodeConditionalExpression (condition = (CCodeExpression) expr.condition.ccodenode, true_expression = (CCodeExpression) expr.true_expression.ccodenode, false_expression = (CCodeExpression) expr.false_expression.ccodenode);
+               foreach (NamedArgument arg in expr.named_argument_list) {
+                       ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (arg.name)));
+                       ccall.add_argument ((CCodeExpression) arg.argument.ccodenode);
                }
+               ccall.add_argument (new CCodeConstant (name = "NULL"));
+               
+               expr.ccodenode = ccall;
+               
+               visit_expression (expr);
+       }
+
+       public override void visit_typeof_expression (TypeofExpression! expr) {
+               expr.ccodenode = new CCodeIdentifier (name = expr.type_reference.type.get_type_id ());
+       }
+
+       public override void visit_unary_expression (UnaryExpression! expr) {
+               CCodeUnaryOperator op;
+               if (expr.operator == UnaryOperator.PLUS) {
+                       op = CCodeUnaryOperator.PLUS;
+               } else if (expr.operator == UnaryOperator.MINUS) {
+                       op = CCodeUnaryOperator.MINUS;
+               } else if (expr.operator == UnaryOperator.LOGICAL_NEGATION) {
+                       op = CCodeUnaryOperator.LOGICAL_NEGATION;
+               } else if (expr.operator == UnaryOperator.BITWISE_COMPLEMENT) {
+                       op = CCodeUnaryOperator.BITWISE_COMPLEMENT;
+               } else if (expr.operator == UnaryOperator.REF) {
+                       op = CCodeUnaryOperator.ADDRESS_OF;
+               } else if (expr.operator == UnaryOperator.OUT) {
+                       op = CCodeUnaryOperator.ADDRESS_OF;
+               }
+               expr.ccodenode = new CCodeUnaryExpression (operator = op, inner = expr.inner.ccodenode);
+               
+               visit_expression (expr);
+       }
 
-               public override void visit_end_lambda_expression (LambdaExpression! l) {
-                       l.ccodenode = new CCodeIdentifier (name = l.method.get_cname ());
+       public override void visit_cast_expression (CastExpression! expr) {
+               if (expr.type_reference.type is Struct || expr.type_reference.type is Enum || expr.type_reference.type is Flags) {
+                       expr.ccodenode = expr.inner.ccodenode;
+               } else {
+                       expr.ccodenode = new InstanceCast (type_reference = expr.type_reference.type, inner = (CCodeExpression) expr.inner.ccodenode);
                }
+               
+               visit_expression (expr);
+       }
 
-               public override void visit_end_assignment (Assignment! a) {
-                       var ma = (MemberAccess) a.left;
+       public override void visit_binary_expression (BinaryExpression! expr) {
+               expr.ccodenode = new CCodeBinaryExpression (operator = expr.operator, left = expr.left.ccodenode, right = expr.right.ccodenode);
+               
+               visit_expression (expr);
+       }
 
-                       if (a.left.symbol_reference.node is Property) {
-                               var prop = (Property) a.left.symbol_reference.node;
-                               var cl = (Class) prop.symbol.parent_symbol.node;
+       public override void visit_type_check (TypeCheck! expr) {
+               var ccheck = new CCodeFunctionCall (call = new CCodeIdentifier (name = expr.type_reference.type.get_upper_case_cname ("IS_")));
+               ccheck.add_argument ((CCodeExpression) expr.expression.ccodenode);
+               expr.ccodenode = ccheck;
+       }
 
-                               var set_func = "g_object_set";
-                               
-                               if (!prop.no_accessor_method) {
-                                       set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
-                               }
-                               
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = set_func));
+       public override void visit_conditional_expression (ConditionalExpression! expr) {
+               expr.ccodenode = new CCodeConditionalExpression (condition = (CCodeExpression) expr.condition.ccodenode, true_expression = (CCodeExpression) expr.true_expression.ccodenode, false_expression = (CCodeExpression) expr.false_expression.ccodenode);
+       }
 
-                               /* target instance is first argument */
-                               ref CCodeExpression instance;
-                               var req_cast = false;
+       public override void visit_end_lambda_expression (LambdaExpression! l) {
+               l.ccodenode = new CCodeIdentifier (name = l.method.get_cname ());
+       }
 
-                               if (ma.inner == null) {
-                                       instance = new CCodeIdentifier (name = "self");
-                                       /* require casts for inherited properties */
-                                       req_cast = (prop.symbol.parent_symbol != current_type_symbol);
-                               } else {
-                                       instance = (CCodeExpression) ma.inner.ccodenode;
-                                       /* require casts if the type of the used instance is
-                                        * different than the type which declared the property */
-                                       req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.type;
-                               }
-                               
-                               if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
-                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                                       ccast.add_argument (instance);
-                                       instance = ccast;
-                               }
+       public override void visit_end_assignment (Assignment! a) {
+               var ma = (MemberAccess) a.left;
 
-                               ccall.add_argument (instance);
-                                       
-                               ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
-                               
-                               if (prop.no_accessor_method) {
-                                       /* property name is second argument of g_object_set */
-                                       ccall.add_argument (prop.get_canonical_cconstant ());
-                               } else if (prop.type_reference.type != null
-                                   && prop.type_reference.type.is_reference_type ()
-                                   && a.right.static_type.type != null
-                                   && prop.type_reference.type != a.right.static_type.type) {
-                                       /* cast is necessary */
-                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = prop.type_reference.type.get_upper_case_cname (null)));
-                                       ccast.add_argument (cexpr);
-                                       cexpr = ccast;
-                               }
-                                       
-                               ccall.add_argument (cexpr);
-                               
-                               if (prop.no_accessor_method) {
-                                       ccall.add_argument (new CCodeConstant (name = "NULL"));
-                               }
-                               
-                               a.ccodenode = ccall;
-                       } else if (a.left.symbol_reference.node is Signal) {
-                               var sig = (Signal) a.left.symbol_reference.node;
+               if (a.left.symbol_reference.node is Property) {
+                       var prop = (Property) a.left.symbol_reference.node;
+                       var cl = (Class) prop.symbol.parent_symbol.node;
+
+                       var set_func = "g_object_set";
+                       
+                       if (!prop.no_accessor_method) {
+                               set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
+                       }
+                       
+                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = set_func));
+
+                       /* target instance is first argument */
+                       ref CCodeExpression instance;
+                       var req_cast = false;
+
+                       if (ma.inner == null) {
+                               instance = new CCodeIdentifier (name = "self");
+                               /* require casts for inherited properties */
+                               req_cast = (prop.symbol.parent_symbol != current_type_symbol);
+                       } else {
+                               instance = (CCodeExpression) ma.inner.ccodenode;
+                               /* require casts if the type of the used instance is
+                                * different than the type which declared the property */
+                               req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.type;
+                       }
+                       
+                       if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
+                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                               ccast.add_argument (instance);
+                               instance = ccast;
+                       }
+
+                       ccall.add_argument (instance);
                                
-                               if (a.right.symbol_reference == null) {
-                                       a.right.error = true;
-                                       Report.error (a.right.source_reference, "unsupported expression for signal handler");
-                                       return;
-                               }
+                       ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
+                       
+                       if (prop.no_accessor_method) {
+                               /* property name is second argument of g_object_set */
+                               ccall.add_argument (prop.get_canonical_cconstant ());
+                       } else if (prop.type_reference.type != null
+                           && prop.type_reference.type.is_reference_type ()
+                           && a.right.static_type.type != null
+                           && prop.type_reference.type != a.right.static_type.type) {
+                               /* cast is necessary */
+                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = prop.type_reference.type.get_upper_case_cname (null)));
+                               ccast.add_argument (cexpr);
+                               cexpr = ccast;
+                       }
                                
-                               var m = (Method) a.right.symbol_reference.node;
-                               var connect_func = "g_signal_connect_object";
-                               if (!m.instance) {
-                                       connect_func = "g_signal_connect";
-                               }
-
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = connect_func));
+                       ccall.add_argument (cexpr);
                        
-                               if (ma.inner != null) {
-                                       ccall.add_argument ((CCodeExpression) ma.inner.ccodenode);
-                               } else {
-                                       ccall.add_argument (new CCodeIdentifier (name = "self"));
-                               }
+                       if (prop.no_accessor_method) {
+                               ccall.add_argument (new CCodeConstant (name = "NULL"));
+                       }
+                       
+                       a.ccodenode = ccall;
+               } 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) {
+                               connect_func = "g_signal_connect";
+                       }
 
-                               ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (sig.name)));
+                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = connect_func));
+               
+                       if (ma.inner != null) {
+                               ccall.add_argument ((CCodeExpression) ma.inner.ccodenode);
+                       } else {
+                               ccall.add_argument (new CCodeIdentifier (name = "self"));
+                       }
 
-                               ccall.add_argument (new CCodeIdentifier (name = m.get_cname ()));
+                       ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (sig.name)));
 
-                               if (m.instance) {
-                                       if (a.right is MemberAccess) {
-                                               var right_ma = (MemberAccess) a.right;
-                                               if (right_ma.inner != null) {
-                                                       ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
-                                               } else {
-                                                       ccall.add_argument (new CCodeIdentifier (name = "self"));
-                                               }
-                                       } else if (a.right is LambdaExpression) {
+                       ccall.add_argument (new CCodeIdentifier (name = m.get_cname ()));
+
+                       if (m.instance) {
+                               if (a.right is MemberAccess) {
+                                       var right_ma = (MemberAccess) a.right;
+                                       if (right_ma.inner != null) {
+                                               ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
+                                       } else {
                                                ccall.add_argument (new CCodeIdentifier (name = "self"));
                                        }
-
-                                       ccall.add_argument (new CCodeConstant (name = "G_CONNECT_SWAPPED"));
-                               } else {
-                                       ccall.add_argument (new CCodeConstant (name = "NULL"));
+                               } else if (a.right is LambdaExpression) {
+                                       ccall.add_argument (new CCodeIdentifier (name = "self"));
                                }
-                               
-                               a.ccodenode = ccall;
+
+                               ccall.add_argument (new CCodeConstant (name = "G_CONNECT_SWAPPED"));
                        } else {
-                               /* explicitly use strong reference as ccast gets
-                                * unrefed at end of inner block
-                                */
-                               ref CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
-                               
-                               if (a.left.static_type.type != null
-                                   && a.right.static_type.type != null
-                                   && a.left.static_type.type.is_reference_type ()
-                                   && a.right.static_type.type != a.left.static_type.type) {
-                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = a.left.static_type.type.get_upper_case_cname (null)));
-                                       ccast.add_argument (rhs);
-                                       rhs = ccast;
-                               }
+                               ccall.add_argument (new CCodeConstant (name = "NULL"));
+                       }
+                       
+                       a.ccodenode = ccall;
+               } else {
+                       /* explicitly use strong reference as ccast gets
+                        * unrefed at end of inner block
+                        */
+                       ref CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
+                       
+                       if (a.left.static_type.type != null
+                           && a.right.static_type.type != null
+                           && a.left.static_type.type.is_reference_type ()
+                           && a.right.static_type.type != a.left.static_type.type) {
+                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = a.left.static_type.type.get_upper_case_cname (null)));
+                               ccast.add_argument (rhs);
+                               rhs = ccast;
+                       }
+                       
+                       if (memory_management && a.left.static_type.is_lvalue_ref) {
+                               /* unref old value */
+                               var ccomma = new CCodeCommaExpression ();
                                
-                               if (memory_management && a.left.static_type.is_lvalue_ref) {
-                                       /* unref old value */
-                                       var ccomma = new CCodeCommaExpression ();
-                                       
-                                       var temp_decl = get_temp_variable_declarator (a.left.static_type);
-                                       temp_vars.prepend (temp_decl);
-                                       ccomma.inner.append (new CCodeAssignment (left = new CCodeIdentifier (name = temp_decl.name), right = rhs));
-                                       ccomma.inner.append (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type));
-                                       ccomma.inner.append (new CCodeIdentifier (name = temp_decl.name));
-                                       
-                                       rhs = ccomma;
-                               }
+                               var temp_decl = get_temp_variable_declarator (a.left.static_type);
+                               temp_vars.prepend (temp_decl);
+                               ccomma.inner.append (new CCodeAssignment (left = new CCodeIdentifier (name = temp_decl.name), right = rhs));
+                               ccomma.inner.append (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type));
+                               ccomma.inner.append (new CCodeIdentifier (name = temp_decl.name));
                                
-                               var cop = CCodeAssignmentOperator.SIMPLE;
-                               if (a.operator == AssignmentOperator.BITWISE_OR) {
-                                       cop = CCodeAssignmentOperator.BITWISE_OR;
-                               } else if (a.operator == AssignmentOperator.BITWISE_AND) {
-                                       cop = CCodeAssignmentOperator.BITWISE_AND;
-                               } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
-                                       cop = CCodeAssignmentOperator.BITWISE_XOR;
-                               } else if (a.operator == AssignmentOperator.ADD) {
-                                       cop = CCodeAssignmentOperator.ADD;
-                               } else if (a.operator == AssignmentOperator.SUB) {
-                                       cop = CCodeAssignmentOperator.SUB;
-                               } else if (a.operator == AssignmentOperator.MUL) {
-                                       cop = CCodeAssignmentOperator.MUL;
-                               } else if (a.operator == AssignmentOperator.DIV) {
-                                       cop = CCodeAssignmentOperator.DIV;
-                               } else if (a.operator == AssignmentOperator.PERCENT) {
-                                       cop = CCodeAssignmentOperator.PERCENT;
-                               } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
-                                       cop = CCodeAssignmentOperator.SHIFT_LEFT;
-                               } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
-                                       cop = CCodeAssignmentOperator.SHIFT_RIGHT;
-                               }
-                       
-                               a.ccodenode = new CCodeAssignment (left = (CCodeExpression) a.left.ccodenode, right = rhs, operator = cop);
+                               rhs = ccomma;
+                       }
+                       
+                       var cop = CCodeAssignmentOperator.SIMPLE;
+                       if (a.operator == AssignmentOperator.BITWISE_OR) {
+                               cop = CCodeAssignmentOperator.BITWISE_OR;
+                       } else if (a.operator == AssignmentOperator.BITWISE_AND) {
+                               cop = CCodeAssignmentOperator.BITWISE_AND;
+                       } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
+                               cop = CCodeAssignmentOperator.BITWISE_XOR;
+                       } else if (a.operator == AssignmentOperator.ADD) {
+                               cop = CCodeAssignmentOperator.ADD;
+                       } else if (a.operator == AssignmentOperator.SUB) {
+                               cop = CCodeAssignmentOperator.SUB;
+                       } else if (a.operator == AssignmentOperator.MUL) {
+                               cop = CCodeAssignmentOperator.MUL;
+                       } else if (a.operator == AssignmentOperator.DIV) {
+                               cop = CCodeAssignmentOperator.DIV;
+                       } else if (a.operator == AssignmentOperator.PERCENT) {
+                               cop = CCodeAssignmentOperator.PERCENT;
+                       } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
+                               cop = CCodeAssignmentOperator.SHIFT_LEFT;
+                       } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
+                               cop = CCodeAssignmentOperator.SHIFT_RIGHT;
                        }
+               
+                       a.ccodenode = new CCodeAssignment (left = (CCodeExpression) a.left.ccodenode, right = rhs, operator = cop);
                }
        }
 }
index a8766b5..6937edf 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class ConditionalExpression : Expression {
-               public Expression condition { get; construct; }
-               public Expression true_expression { get; construct; }
-               public Expression false_expression { get; construct; }
-               
-               public static ref ConditionalExpression new (Expression cond, Expression true_expr, Expression false_expr, SourceReference source) {
-                       return (new ConditionalExpression (condition = cond, true_expression = true_expr, false_expression = false_expr, source_reference = source));
-               }
-               
-               public override void accept (CodeVisitor visitor) {
-                       condition.accept (visitor);
-                       true_expression.accept (visitor);
-                       false_expression.accept (visitor);                      
+/**
+ * Represents a conditional expression in the source code.
+ */
+public class Vala.ConditionalExpression : Expression {
+       /**
+        * The condition.
+        */
+       public Expression! condition { get; set construct; }
+       
+       /**
+        * The expression to be evaluated if the condition holds.
+        */
+       public Expression! true_expression { get; set construct; }
+
+       /**
+        * The expression to be evaluated if the condition doesn't hold.
+        */
+       public Expression! false_expression { get; set construct; }
+       
+       /**
+        * Creates a new conditional expression.
+        *
+        * @param cond       a condition
+        * @param true_expr  expression to be evaluated if condition is true
+        * @param false_expr expression to be evaluated if condition is false
+        * @return           newly created conditional expression
+        */
+       public static ref ConditionalExpression! new (Expression! cond, Expression! true_expr, Expression! false_expr, SourceReference source) {
+               return (new ConditionalExpression (condition = cond, true_expression = true_expr, false_expression = false_expr, source_reference = source));
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               condition.accept (visitor);
+               true_expression.accept (visitor);
+               false_expression.accept (visitor);                      
 
-                       visitor.visit_conditional_expression (this);
-               }
+               visitor.visit_conditional_expression (this);
        }
 }
index c4dc7d6..ff19657 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class Constant : CodeNode {
-               public string name { get; construct; }
-               public TypeReference type_reference { get; construct; }
-               public Expression initializer { get; construct; }
-               public SourceReference source_reference { get; construct; }
-               
-               public static ref Constant new (string name, TypeReference type, Expression init, SourceReference source) {
-                       return (new Constant (name = name, type_reference = type, initializer = init, source_reference = source));
-               }
-               
-               public override void accept (CodeVisitor visitor) {
-                       type_reference.accept (visitor);
-                       
-                       initializer.accept (visitor);
+/**
+ * Represents a type member with a constant value.
+ */
+public class Vala.Constant : CodeNode {
+       /**
+        * The symbol name of this constant.
+        */
+       public string! name { get; set construct; }
 
-                       visitor.visit_constant (this);
-               }
+       /**
+        * The data type of this constant.
+        */
+       public TypeReference! type_reference { get; set construct; }
+
+       /**
+        * The value of this constant.
+        */
+       public Expression! initializer { get; set construct; }
+       
+       private string cname;
+
+       /**
+        * Creates a new constant.
+        *
+        * @param name   constant name
+        * @param type   constant type
+        * @param init   constant value
+        * @param source reference to source code
+        * @return       newly created constant
+        */
+       public static ref Constant! new (string! name, TypeReference! type, Expression! init, SourceReference source) {
+               return (new Constant (name = name, type_reference = type, initializer = init, source_reference = source));
+       }
+       
+       public override void accept (CodeVisitor visitor) {
+               type_reference.accept (visitor);
                
-               string cname;
-               public string get_cname () {
-                       if (cname == null) {
-                               if (symbol.parent_symbol.node is DataType) {
-                                       var t = (DataType) symbol.parent_symbol.node;
-                                       cname = "%s_%s".printf (t.get_upper_case_cname (null), name);
-                               } else {
-                                       var ns = (Namespace) symbol.parent_symbol.node;
-                                       cname = "%s%s".printf (ns.get_cprefix ().up (), name);
-                               }
+               initializer.accept (visitor);
+
+               visitor.visit_constant (this);
+       }
+       
+       /**
+        * Returns the name of this constant as it is used in C code.
+        *
+        * @return the name to be used in C code
+        */
+       public string! get_cname () {
+               if (cname == null) {
+                       if (symbol.parent_symbol.node is DataType) {
+                               var t = (DataType) symbol.parent_symbol.node;
+                               cname = "%s_%s".printf (t.get_upper_case_cname (null), name);
+                       } else {
+                               var ns = (Namespace) symbol.parent_symbol.node;
+                               cname = "%s%s".printf (ns.get_cprefix ().up (), name);
                        }
-                       return cname;
                }
+               return cname;
        }
 }
index e288060..7ac01d3 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class MemoryManager : CodeVisitor {
-               Symbol current_symbol;
-
-               public void analyze (CodeContext! context) {
-                       context.accept (this);
-               }
-               
-               private void visit_possibly_leaked_expression (Expression! expr) {
-                       if (expr.static_type != null &&
-                           expr.static_type.is_ref) {
-                               /* mark reference as leaked */
-                               expr.ref_leaked = true;
-                       }
+/**
+ * Code visitor analyzing memory usage. The memory manager finds leaked and
+ * copied references.
+ */
+public class Vala.MemoryManager : CodeVisitor {
+       Symbol current_symbol;
+
+       /**
+        * Analyze memory usage in the specified code context.
+        *
+        * @param context a code context
+        */
+       public void analyze (CodeContext! context) {
+               context.accept (this);
+       }
+       
+       private void visit_possibly_leaked_expression (Expression! expr) {
+               if (expr.static_type != null &&
+                   expr.static_type.is_ref) {
+                       /* mark reference as leaked */
+                       expr.ref_leaked = true;
                }
+       }
 
-               private void visit_possibly_missing_copy_expression (Expression! expr) {
-                       if (expr.static_type != null &&
-                           (expr.static_type.type != null &&
-                            expr.static_type.type.is_reference_type ()) &&
-                           !expr.static_type.is_ref) {
-                               /* mark reference as missing */
-                               expr.ref_missing = true;
-                       }
+       private void visit_possibly_missing_copy_expression (Expression! expr) {
+               if (expr.static_type != null &&
+                   (expr.static_type.type != null &&
+                    expr.static_type.type.is_reference_type ()) &&
+                   !expr.static_type.is_ref) {
+                       /* mark reference as missing */
+                       expr.ref_missing = true;
                }
+       }
 
-               public override void visit_begin_method (Method! m) {
-                       current_symbol = m.symbol;
-               }
-               
-               public override void visit_begin_property (Property prop) {
-                       current_symbol = prop.symbol;
-               }
+       public override void visit_begin_method (Method! m) {
+               current_symbol = m.symbol;
+       }
+       
+       public override void visit_begin_property (Property prop) {
+               current_symbol = prop.symbol;
+       }
 
-               public override void visit_named_argument (NamedArgument! n) {
-                       visit_possibly_leaked_expression (n.argument);
-               }
+       public override void visit_named_argument (NamedArgument! n) {
+               visit_possibly_leaked_expression (n.argument);
+       }
 
-               public override void visit_variable_declarator (VariableDeclarator! decl) {
-                       if (decl.initializer != null) {
-                               if (decl.type_reference.is_lvalue_ref) {
-                                       visit_possibly_missing_copy_expression (decl.initializer);
-                               } else {
-                                       visit_possibly_leaked_expression (decl.initializer);
-                               }
+       public override void visit_variable_declarator (VariableDeclarator! decl) {
+               if (decl.initializer != null) {
+                       if (decl.type_reference.is_lvalue_ref) {
+                               visit_possibly_missing_copy_expression (decl.initializer);
+                       } else {
+                               visit_possibly_leaked_expression (decl.initializer);
                        }
                }
+       }
 
-               public override void visit_expression_statement (ExpressionStatement! stmt) {
-                       visit_possibly_leaked_expression (stmt.expression);
-               }
+       public override void visit_expression_statement (ExpressionStatement! stmt) {
+               visit_possibly_leaked_expression (stmt.expression);
+       }
 
-               public override void visit_return_statement (ReturnStatement! stmt) {
-                       if (stmt.return_expression != null) {
-                               if (current_symbol.node is Method) {
-                                       var m = (Method) current_symbol.node;
-                                       
-                                       if (m.return_type.is_ref) {
-                                               visit_possibly_missing_copy_expression (stmt.return_expression);
-                                       } else {
-                                               visit_possibly_leaked_expression (stmt.return_expression);
-                                       }
+       public override void visit_return_statement (ReturnStatement! stmt) {
+               if (stmt.return_expression != null) {
+                       if (current_symbol.node is Method) {
+                               var m = (Method) current_symbol.node;
+                               
+                               if (m.return_type.is_ref) {
+                                       visit_possibly_missing_copy_expression (stmt.return_expression);
                                } else {
-                                       /* property get accessor */
                                        visit_possibly_leaked_expression (stmt.return_expression);
                                }
+                       } else {
+                               /* property get accessor */
+                               visit_possibly_leaked_expression (stmt.return_expression);
                        }
                }
+       }
 
-               public override void visit_member_access (MemberAccess! expr) {
-                       if (expr.inner != null) {
-                               visit_possibly_leaked_expression (expr.inner);
-                       }
+       public override void visit_member_access (MemberAccess! expr) {
+               if (expr.inner != null) {
+                       visit_possibly_leaked_expression (expr.inner);
                }
+       }
 
-               public override void visit_end_invocation_expression (InvocationExpression! expr) {
-                       List<FormalParameter> params;
-                       
-                       var msym = expr.call.symbol_reference;
-                       if (msym.node is VariableDeclarator) {
-                               var decl = (VariableDeclarator) msym.node;
-                               var cb = (Callback) decl.type_reference.type;
-                               params = cb.get_parameters ();
-                       } else if (msym.node is FormalParameter) {
-                               var param = (FormalParameter) msym.node;
-                               var cb = (Callback) param.type_reference.type;
-                               params = cb.get_parameters ();
-                       } else {
-                               var m = (Method) msym.node;
-                               params = m.get_parameters ();
-                       }
-                       foreach (Expression arg in expr.argument_list) {
-                               if (params != null) {
-                                       var param = (FormalParameter) params.data;
-                                       if (!param.ellipsis
-                                           && ((param.type_reference.type != null
-                                           && param.type_reference.type.is_reference_type ())
-                                           || param.type_reference.type_parameter != null)) {
-                                               bool is_ref = param.type_reference.is_ref;
-                                               if (is_ref && param.type_reference.type_parameter != null) {
-                                                       if (expr.call is MemberAccess) {
-                                                               var instance_type = ((MemberAccess) expr.call).inner.static_type;
-                                                               foreach (TypeReference type_arg in instance_type.get_type_arguments ()) {
-                                                                       /* generic method parameters may only be strong references if the type argument is strong, too */
-                                                                       is_ref = type_arg.is_ref;
-                                                               }
+       public override void visit_end_invocation_expression (InvocationExpression! expr) {
+               List<FormalParameter> params;
+               
+               var msym = expr.call.symbol_reference;
+               if (msym.node is VariableDeclarator) {
+                       var decl = (VariableDeclarator) msym.node;
+                       var cb = (Callback) decl.type_reference.type;
+                       params = cb.get_parameters ();
+               } else if (msym.node is FormalParameter) {
+                       var param = (FormalParameter) msym.node;
+                       var cb = (Callback) param.type_reference.type;
+                       params = cb.get_parameters ();
+               } else {
+                       var m = (Method) msym.node;
+                       params = m.get_parameters ();
+               }
+               foreach (Expression arg in expr.argument_list) {
+                       if (params != null) {
+                               var param = (FormalParameter) params.data;
+                               if (!param.ellipsis
+                                   && ((param.type_reference.type != null
+                                   && param.type_reference.type.is_reference_type ())
+                                   || param.type_reference.type_parameter != null)) {
+                                       bool is_ref = param.type_reference.is_ref;
+                                       if (is_ref && param.type_reference.type_parameter != null) {
+                                               if (expr.call is MemberAccess) {
+                                                       var instance_type = ((MemberAccess) expr.call).inner.static_type;
+                                                       foreach (TypeReference type_arg in instance_type.get_type_arguments ()) {
+                                                               /* generic method parameters may only be strong references if the type argument is strong, too */
+                                                               is_ref = type_arg.is_ref;
                                                        }
                                                }
-                                               
-                                               if (is_ref) {
-                                                       visit_possibly_missing_copy_expression (arg);
-                                               } else {
-                                                       visit_possibly_leaked_expression (arg);
-                                               }
+                                       }
+                                       
+                                       if (is_ref) {
+                                               visit_possibly_missing_copy_expression (arg);
                                        } else {
                                                visit_possibly_leaked_expression (arg);
                                        }
-
-                                       params = params.next;
                                } else {
                                        visit_possibly_leaked_expression (arg);
                                }
+
+                               params = params.next;
+                       } else {
+                               visit_possibly_leaked_expression (arg);
                        }
                }
+       }
 
-               public override void visit_binary_expression (BinaryExpression! expr) {
-                       visit_possibly_leaked_expression (expr.left);
-                       visit_possibly_leaked_expression (expr.right);
-               }
+       public override void visit_binary_expression (BinaryExpression! expr) {
+               visit_possibly_leaked_expression (expr.left);
+               visit_possibly_leaked_expression (expr.right);
+       }
 
-               public override void visit_end_assignment (Assignment! a) {
-                       if (a.left.symbol_reference.node is Signal) {
+       public override void visit_end_assignment (Assignment! a) {
+               if (a.left.symbol_reference.node is Signal) {
+               } else {
+                       if (a.left.static_type.is_lvalue_ref) {
+                               visit_possibly_missing_copy_expression (a.right);
                        } else {
-                               if (a.left.static_type.is_lvalue_ref) {
-                                       visit_possibly_missing_copy_expression (a.right);
-                               } else {
-                                       visit_possibly_leaked_expression (a.right);
-                               }
+                               visit_possibly_leaked_expression (a.right);
                        }
                }
        }
index 62c373e..4741dfa 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class SemanticAnalyzer : CodeVisitor {
-               public bool memory_management { get; construct; }
-               
-               Symbol root_symbol;
-               Symbol current_symbol;
-               SourceFile current_source_file;
-               TypeReference current_return_type;
+/**
+ * Code visitor analyzing and checking code.
+ */
+public class Vala.SemanticAnalyzer : CodeVisitor {
+       /**
+        * Specifies whether automatic memory management is active.
+        */
+       public bool memory_management { get; set; }
+       
+       Symbol root_symbol;
+       Symbol current_symbol;
+       SourceFile current_source_file;
+       TypeReference current_return_type;
+       
+       List<weak NamespaceReference> current_using_directives;
+       
+       TypeReference bool_type;
+       TypeReference string_type;
+       DataType initially_unowned_type;
+
+       private int next_lambda_id = 0;
+       
+       /**
+        * Analyze and check code in the specified context.
+        *
+        * @param context a code context
+        */
+       public void analyze (CodeContext! context) {
+               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;
                
-               List<weak NamespaceReference> current_using_directives;
+               var glib_ns = root_symbol.lookup ("GLib");
                
-               TypeReference bool_type;
-               TypeReference string_type;
-               DataType initially_unowned_type;
+               initially_unowned_type = (DataType) glib_ns.lookup ("InitiallyUnowned").node;
 
-               private int next_lambda_id = 0;
+               current_symbol = root_symbol;
+               context.accept (this);
+       }
+       
+       public override void visit_begin_source_file (SourceFile! file) {
+               current_source_file = file;
+               current_using_directives = file.get_using_directives ();
                
-               public void analyze (CodeContext context) {
-                       root_symbol = context.get_root ();
+               next_lambda_id = 0;
+       }
 
-                       bool_type = new TypeReference ();
-                       bool_type.type = (DataType) root_symbol.lookup ("bool").node;
+       public override void visit_end_source_file (SourceFile! file) {
+               current_using_directives = null;
+       }
 
-                       string_type = new TypeReference ();
-                       string_type.type = (DataType) root_symbol.lookup ("string").node;
-                       
-                       var glib_ns = root_symbol.lookup ("GLib");
-                       
-                       initially_unowned_type = (DataType) glib_ns.lookup ("InitiallyUnowned").node;
+       public override void visit_begin_namespace (Namespace! ns) {
+               current_symbol = ns.symbol;
+       }
 
-                       current_symbol = root_symbol;
-                       context.accept (this);
-               }
+       public override void visit_end_namespace (Namespace! ns) {
+               current_symbol = current_symbol.parent_symbol;
+       }
+
+       public override void visit_begin_class (Class! cl) {
+               current_symbol = cl.symbol;
                
-               public override void visit_begin_source_file (SourceFile! file) {
-                       current_source_file = file;
-                       current_using_directives = file.get_using_directives ();
-                       
-                       next_lambda_id = 0;
+               if (cl.base_class != null) {
+                       current_source_file.add_symbol_dependency (cl.base_class.symbol, SourceFileDependencyType.HEADER_FULL);
                }
+       }
 
-               public override void visit_end_source_file (SourceFile! file) {
-                       current_using_directives = null;
-               }
+       public override void visit_end_class (Class! cl) {
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_begin_namespace (Namespace! ns) {
-                       current_symbol = ns.symbol;
-               }
+       public override void visit_begin_struct (Struct! st) {
+               current_symbol = st.symbol;
+       }
 
-               public override void visit_end_namespace (Namespace! ns) {
-                       current_symbol = current_symbol.parent_symbol;
-               }
+       public override void visit_end_struct (Struct! st) {
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               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_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);
                        }
-               }
-
-               public override void visit_end_class (Class! cl) {
-                       current_symbol = current_symbol.parent_symbol;
-               }
-
-               public override void visit_begin_struct (Struct! st) {
-                       current_symbol = st.symbol;
-               }
-
-               public override void visit_end_struct (Struct! st) {
-                       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);
-                               }
+               } 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;
-                       current_return_type = m.return_type;
-                       
-                       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_begin_method (Method! m) {
+               current_symbol = m.symbol;
+               current_return_type = m.return_type;
+               
+               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;
-                       current_return_type = null;
+       public override void visit_end_method (Method! m) {
+               current_symbol = current_symbol.parent_symbol;
+               current_return_type = null;
 
-                       if (current_symbol.parent_symbol.node is Method) {
-                               /* lambda expressions produce nested methods */
-                               var up_method = (Method) current_symbol.parent_symbol.node;
-                               current_return_type = up_method.return_type;
-                       }
-                       
-                       if (m.is_virtual || m.is_override) {
-                               if (current_symbol.node is Class) {
-                                       var cl = (Class) current_symbol.node;
-                                       Class base_class;
-                                       for (base_class = cl; base_class != null; base_class = base_class.base_class) {
-                                               var sym = base_class.symbol.lookup (m.name);
-                                               if (sym != null && sym.node is Method) {
-                                                       var base_method = (Method) sym.node;
-                                                       if (base_method.is_abstract || base_method.is_virtual) {
-                                                               m.base_method = base_method;
-                                                               break;
-                                                       }
+               if (current_symbol.parent_symbol.node is Method) {
+                       /* lambda expressions produce nested methods */
+                       var up_method = (Method) current_symbol.parent_symbol.node;
+                       current_return_type = up_method.return_type;
+               }
+               
+               if (m.is_virtual || m.is_override) {
+                       if (current_symbol.node is Class) {
+                               var cl = (Class) current_symbol.node;
+                               Class base_class;
+                               for (base_class = cl; base_class != null; base_class = base_class.base_class) {
+                                       var sym = base_class.symbol.lookup (m.name);
+                                       if (sym != null && sym.node is Method) {
+                                               var base_method = (Method) sym.node;
+                                               if (base_method.is_abstract || base_method.is_virtual) {
+                                                       m.base_method = base_method;
+                                                       break;
                                                }
                                        }
-                                       if (m.base_method == null) {
-                                               /* FIXME: also look at interfaces implemented
-                                                * by one of the base types
-                                                */
-                                               foreach (TypeReference type in cl.get_base_types ()) {
-                                                       if (type.type is Interface) {
-                                                               var iface = (Interface) type.type;
-                                                               var sym = iface.symbol.lookup (m.name);
-                                                               if (sym != null && sym.node is Method) {
-                                                                       var base_method = (Method) sym.node;
-                                                                       if (base_method.is_abstract || base_method.is_virtual) {
-                                                                               m.base_method = base_method;
-                                                                               break;
-                                                                       }
+                               }
+                               if (m.base_method == null) {
+                                       /* FIXME: also look at interfaces implemented
+                                        * by one of the base types
+                                        */
+                                       foreach (TypeReference type in cl.get_base_types ()) {
+                                               if (type.type is Interface) {
+                                                       var iface = (Interface) type.type;
+                                                       var sym = iface.symbol.lookup (m.name);
+                                                       if (sym != null && sym.node is Method) {
+                                                               var base_method = (Method) sym.node;
+                                                               if (base_method.is_abstract || base_method.is_virtual) {
+                                                                       m.base_method = base_method;
+                                                                       break;
                                                                }
                                                        }
                                                }
                                        }
-                                       if (m.base_method == null) {
-                                               Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.symbol.get_full_name ()));
-                                       }
-                               } else if (current_symbol.node is Struct) {
-                                       Report.error (m.source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (m.symbol.get_full_name ()));
-                                       return;
                                }
-                       }
-               }
-
-               public override void visit_formal_parameter (FormalParameter! p) {
-                       if (!p.ellipsis) {
-                               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);
-                                       current_source_file.add_symbol_dependency (p.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+                               if (m.base_method == null) {
+                                       Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.symbol.get_full_name ()));
                                }
+                       } else if (current_symbol.node is Struct) {
+                               Report.error (m.source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (m.symbol.get_full_name ()));
+                               return;
                        }
                }
+       }
 
-               public override void visit_end_property (Property! prop) {
-                       if (prop.type_reference.type != null) {
+       public override void visit_formal_parameter (FormalParameter! p) {
+               if (!p.ellipsis) {
+                       if (p.type_reference.type != null) {
                                /* is null if it references a type parameter */
-                               current_source_file.add_symbol_dependency (prop.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
-                               current_source_file.add_symbol_dependency (prop.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+                               current_source_file.add_symbol_dependency (p.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+                               current_source_file.add_symbol_dependency (p.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
                        }
                }
+       }
 
-               public override void visit_begin_property_accessor (PropertyAccessor! acc) {
-                       var prop = (Property) acc.symbol.parent_symbol.node;
-                       
-                       if (acc.readable) {
-                               current_return_type = prop.type_reference;
-                       }
+       public override void visit_end_property (Property! prop) {
+               if (prop.type_reference.type != null) {
+                       /* is null if it references a type parameter */
+                       current_source_file.add_symbol_dependency (prop.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+                       current_source_file.add_symbol_dependency (prop.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
                }
+       }
 
-               public override void visit_end_property_accessor (PropertyAccessor! acc) {
-                       current_return_type = null;
+       public override void visit_begin_property_accessor (PropertyAccessor! acc) {
+               var prop = (Property) acc.symbol.parent_symbol.node;
+               
+               if (acc.readable) {
+                       current_return_type = prop.type_reference;
                }
+       }
 
-               public override void visit_begin_constructor (Constructor! c) {
-                       current_symbol = c.symbol;
-               }
+       public override void visit_end_property_accessor (PropertyAccessor! acc) {
+               current_return_type = null;
+       }
 
-               public override void visit_end_constructor (Constructor! c) {
-                       current_symbol = current_symbol.parent_symbol;
-               }
+       public override void visit_begin_constructor (Constructor! c) {
+               current_symbol = c.symbol;
+       }
 
-               public override void visit_begin_destructor (Destructor! d) {
-                       current_symbol = d.symbol;
-               }
+       public override void visit_end_constructor (Constructor! c) {
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_end_destructor (Destructor! d) {
-                       current_symbol = current_symbol.parent_symbol;
-               }
+       public override void visit_begin_destructor (Destructor! d) {
+               current_symbol = d.symbol;
+       }
 
-               public override void visit_named_argument (NamedArgument! n) {
-               }
+       public override void visit_end_destructor (Destructor! d) {
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_begin_block (Block! b) {
-                       current_symbol = b.symbol;
+       public override void visit_named_argument (NamedArgument! n) {
+       }
+
+       public override void visit_begin_block (Block! b) {
+               current_symbol = b.symbol;
+       }
+
+       public override void visit_end_block (Block! b) {
+               foreach (VariableDeclarator decl in b.get_local_variables ()) {
+                       decl.symbol.active = false;
                }
+       
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_end_block (Block! b) {
-                       foreach (VariableDeclarator decl in b.get_local_variables ()) {
-                               decl.symbol.active = false;
+       public override void visit_variable_declarator (VariableDeclarator! decl) {
+               if (decl.type_reference == null) {
+                       /* var type */
+                       
+                       if (decl.initializer == null) {
+                               decl.error = true;
+                               Report.error (decl.source_reference, "var declaration not allowed without initializer");
+                               return;
                        }
-               
-                       current_symbol = current_symbol.parent_symbol;
+                       if (decl.initializer.static_type == null) {
+                               decl.error = true;
+                               Report.error (decl.source_reference, "var declaration not allowed with non-typed initializer");
+                               return;
+                       }
+                       
+                       decl.type_reference = decl.initializer.static_type.copy ();
+                       decl.type_reference.is_lvalue_ref = decl.type_reference.is_ref;
+                       decl.type_reference.is_ref = false;
                }
-
-               public override void visit_variable_declarator (VariableDeclarator! decl) {
-                       if (decl.type_reference == null) {
-                               /* var type */
-                               
-                               if (decl.initializer == null) {
-                                       decl.error = true;
-                                       Report.error (decl.source_reference, "var declaration not allowed without initializer");
-                                       return;
-                               }
-                               if (decl.initializer.static_type == null) {
+               
+               if (decl.initializer != null) {
+                       if (decl.initializer.static_type == null) {
+                               if (!(decl.initializer is MemberAccess)) {
                                        decl.error = true;
-                                       Report.error (decl.source_reference, "var declaration not allowed with non-typed initializer");
+                                       Report.error (decl.source_reference, "expression type not allowed as initializer");
                                        return;
                                }
                                
-                               decl.type_reference = decl.initializer.static_type.copy ();
-                               decl.type_reference.is_lvalue_ref = decl.type_reference.is_ref;
-                               decl.type_reference.is_ref = false;
-                       }
-                       
-                       if (decl.initializer != null) {
-                               if (decl.initializer.static_type == null) {
-                                       if (!(decl.initializer is MemberAccess)) {
-                                               decl.error = true;
-                                               Report.error (decl.source_reference, "expression type not allowed as initializer");
-                                               return;
-                                       }
+                               if (decl.initializer.symbol_reference.node is Method &&
+                                   decl.type_reference.type is Callback) {
+                                       var m = (Method) decl.initializer.symbol_reference.node;
+                                       var cb = (Callback) decl.type_reference.type;
                                        
-                                       if (decl.initializer.symbol_reference.node is Method &&
-                                           decl.type_reference.type is Callback) {
-                                               var m = (Method) decl.initializer.symbol_reference.node;
-                                               var cb = (Callback) decl.type_reference.type;
-                                               
-                                               /* check whether method matches callback type */
-                                               if (!cb.matches_method (m)) {
-                                                       decl.error = true;
-                                                       Report.error (decl.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.symbol.get_full_name (), cb.symbol.get_full_name ()));
-                                                       return;
-                                               }
-                                               
-                                               decl.initializer.static_type = decl.type_reference;
-                                       } else {
+                                       /* check whether method matches callback type */
+                                       if (!cb.matches_method (m)) {
                                                decl.error = true;
-                                               Report.error (decl.source_reference, "expression type not allowed as initializer");
+                                               Report.error (decl.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.symbol.get_full_name (), cb.symbol.get_full_name ()));
                                                return;
                                        }
+                                       
+                                       decl.initializer.static_type = decl.type_reference;
+                               } else {
+                                       decl.error = true;
+                                       Report.error (decl.source_reference, "expression type not allowed as initializer");
+                                       return;
                                }
-                       
-                               if (memory_management) {
-                                       if (decl.initializer.static_type.is_ref) {
-                                               /* rhs transfers ownership of the expression */
-                                               if (!decl.type_reference.is_lvalue_ref) {
-                                                       /* lhs doesn't own the value
-                                                        * promote lhs type */
-                                                       
-                                                       decl.type_reference.is_lvalue_ref = true;
-                                               }
+                       }
+               
+                       if (memory_management) {
+                               if (decl.initializer.static_type.is_ref) {
+                                       /* rhs transfers ownership of the expression */
+                                       if (!decl.type_reference.is_lvalue_ref) {
+                                               /* lhs doesn't own the value
+                                                * promote lhs type */
+                                               
+                                               decl.type_reference.is_lvalue_ref = true;
                                        }
                                }
                        }
-                       
-                       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);
-                       
-                       var block = (Block) current_symbol.node;
-                       block.add_local_variable (decl);
-                       
-                       decl.symbol.active = true;
                }
-
-               public override void visit_expression_statement (ExpressionStatement! stmt) {
-                       if (stmt.expression.static_type != null &&
-                           stmt.expression.static_type.is_ref) {
-                               Report.warning (stmt.source_reference, "Short-living reference");
-                               return;
-                       }
+               
+               if (decl.type_reference.type != null) {
+                       current_source_file.add_symbol_dependency (decl.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
                }
 
-               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.variable_declarator = new VariableDeclarator (name = stmt.variable_name);
-                       stmt.variable_declarator.type_reference = stmt.type_reference;
+               decl.symbol = new Symbol (node = decl);
+               current_symbol.add (decl.name, decl.symbol);
                
-                       stmt.variable_declarator.symbol = new Symbol (node = stmt.variable_declarator);
-                       current_symbol.add (stmt.variable_name, stmt.variable_declarator.symbol);
-               }
+               var block = (Block) current_symbol.node;
+               block.add_local_variable (decl);
+               
+               decl.symbol.active = true;
+       }
 
-               public override void visit_return_statement (ReturnStatement! stmt) {
-                       if (current_return_type == null) {
-                               Report.error (stmt.source_reference, "Return not allowed in this context");
-                               return;
-                       }
-                       
-                       if (stmt.return_expression == null && current_return_type.type != null) {
-                               Report.error (stmt.source_reference, "Return with value in void function");
-                               return;
-                       }
-                       
-                       if (stmt.return_expression != null && current_return_type.type == null) {
-                               Report.error (stmt.source_reference, "Return without value in non-void function");
-                               return;
-                       }
-                       
-                       if (stmt.return_expression != null &&
-                            !is_type_compatible (stmt.return_expression.static_type, current_return_type)) {
-                               Report.error (stmt.source_reference, "Return: Cannot convert from `%s' to `%s'".printf (stmt.return_expression.static_type.to_string (), current_return_type.to_string ()));
-                               return;
-                       }
-                       
+       public override void visit_expression_statement (ExpressionStatement! stmt) {
+               if (stmt.expression.static_type != null &&
+                   stmt.expression.static_type.is_ref) {
+                       Report.warning (stmt.source_reference, "Short-living reference");
+                       return;
                }
+       }
 
-               public override void visit_boolean_literal (BooleanLiteral! expr) {
-                       expr.static_type = bool_type;
+       public override void visit_if_statement (IfStatement! stmt) {
+               if (stmt.condition.static_type.type != bool_type.type) {
+                       stmt.error = true;
+                       Report.error (stmt.condition.source_reference, "Condition must be boolean");
+                       return;
                }
+       }
 
-               public override void visit_character_literal (CharacterLiteral! expr) {
-                       expr.static_type = new TypeReference ();
-                       expr.static_type.type = (DataType) root_symbol.lookup ("char").node;
+       public override void visit_while_statement (WhileStatement! stmt) {
+               if (stmt.condition.static_type.type != bool_type.type) {
+                       stmt.error = true;
+                       Report.error (stmt.condition.source_reference, "Condition must be boolean");
+                       return;
                }
+       }
 
-               public override void visit_integer_literal (IntegerLiteral! expr) {
-                       expr.static_type = new TypeReference ();
-                       expr.static_type.type = (DataType) root_symbol.lookup ("int").node;
+       public override void visit_for_statement (ForStatement! stmt) {
+               if (stmt.condition.static_type.type != bool_type.type) {
+                       stmt.error = true;
+                       Report.error (stmt.condition.source_reference, "Condition must be boolean");
+                       return;
                }
+       }
 
-               public override void visit_real_literal (IntegerLiteral! expr) {
-                       expr.static_type = new TypeReference ();
-                       expr.static_type.type = (DataType) root_symbol.lookup ("double").node;
+       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.variable_declarator = new VariableDeclarator (name = stmt.variable_name);
+               stmt.variable_declarator.type_reference = stmt.type_reference;
+       
+               stmt.variable_declarator.symbol = new Symbol (node = stmt.variable_declarator);
+               current_symbol.add (stmt.variable_name, stmt.variable_declarator.symbol);
+       }
 
-               public override void visit_string_literal (StringLiteral! expr) {
-                       expr.static_type = string_type;
+       public override void visit_return_statement (ReturnStatement! stmt) {
+               if (current_return_type == null) {
+                       Report.error (stmt.source_reference, "Return not allowed in this context");
+                       return;
+               }
+               
+               if (stmt.return_expression == null && current_return_type.type != null) {
+                       Report.error (stmt.source_reference, "Return with value in void function");
+                       return;
                }
+               
+               if (stmt.return_expression != null && current_return_type.type == null) {
+                       Report.error (stmt.source_reference, "Return without value in non-void function");
+                       return;
+               }
+               
+               if (stmt.return_expression != null &&
+                    !is_type_compatible (stmt.return_expression.static_type, current_return_type)) {
+                       Report.error (stmt.source_reference, "Return: Cannot convert from `%s' to `%s'".printf (stmt.return_expression.static_type.to_string (), current_return_type.to_string ()));
+                       return;
+               }
+               
+       }
 
-               public override void visit_null_literal (NullLiteral! expr) {
-                       /* empty TypeReference represents null */
-                       
-                       expr.static_type = new TypeReference ();
-               }
-
-               public override void visit_literal_expression (LiteralExpression! expr) {
-                       expr.static_type = expr.literal.static_type;
-               }
-               
-               ref TypeReference get_static_type_for_node (CodeNode! node) {
-                       if (node is Field) {
-                               var f = (Field) node;
-                               return f.type_reference;
-                       } else if (node is Constant) {
-                               var c = (Constant) node;
-                               return c.type_reference;
-                       } else if (node is Property) {
-                               var prop = (Property) node;
-                               var type = prop.type_reference.copy ();
-                               type.is_lvalue_ref = false;
-                               return type;
-                       } else if (node is FormalParameter) {
-                               var p = (FormalParameter) node;
-                               return p.type_reference;
-                       } else if (node is TypeReference) {
-                               return (TypeReference) node;
-                       } else if (node is VariableDeclarator) {
-                               var decl = (VariableDeclarator) node;
-                               return decl.type_reference;
-                       } else if (node is EnumValue) {
-                               var type = new TypeReference ();
-                               type.type = (DataType) node.symbol.parent_symbol.node;
-                               return type;
-                       }
-                       return null;
-               }
-               
-               Symbol symbol_lookup_inherited (Symbol! sym, string! name) {
-                       var result = sym.lookup (name);
-                       if (result == null && sym.node is Class) {
-                               var cl = (Class) sym.node;
-                               for (cl = cl.base_class; cl != null && result == null; cl = cl.base_class) {
-                                       result = cl.symbol.lookup (name);
-                               }
+       public override void visit_boolean_literal (BooleanLiteral! expr) {
+               expr.static_type = bool_type;
+       }
+
+       public override void visit_character_literal (CharacterLiteral! expr) {
+               expr.static_type = new TypeReference ();
+               expr.static_type.type = (DataType) root_symbol.lookup ("char").node;
+       }
+
+       public override void visit_integer_literal (IntegerLiteral! expr) {
+               expr.static_type = new TypeReference ();
+               expr.static_type.type = (DataType) root_symbol.lookup ("int").node;
+       }
+
+       public override void visit_real_literal (IntegerLiteral! expr) {
+               expr.static_type = new TypeReference ();
+               expr.static_type.type = (DataType) root_symbol.lookup ("double").node;
+       }
+
+       public override void visit_string_literal (StringLiteral! expr) {
+               expr.static_type = string_type;
+       }
+
+       public override void visit_null_literal (NullLiteral! expr) {
+               /* empty TypeReference represents null */
+               
+               expr.static_type = new TypeReference ();
+       }
+
+       public override void visit_literal_expression (LiteralExpression! expr) {
+               expr.static_type = expr.literal.static_type;
+       }
+       
+       ref TypeReference get_static_type_for_node (CodeNode! node) {
+               if (node is Field) {
+                       var f = (Field) node;
+                       return f.type_reference;
+               } else if (node is Constant) {
+                       var c = (Constant) node;
+                       return c.type_reference;
+               } else if (node is Property) {
+                       var prop = (Property) node;
+                       var type = prop.type_reference.copy ();
+                       type.is_lvalue_ref = false;
+                       return type;
+               } else if (node is FormalParameter) {
+                       var p = (FormalParameter) node;
+                       return p.type_reference;
+               } else if (node is TypeReference) {
+                       return (TypeReference) node;
+               } else if (node is VariableDeclarator) {
+                       var decl = (VariableDeclarator) node;
+                       return decl.type_reference;
+               } else if (node is EnumValue) {
+                       var type = new TypeReference ();
+                       type.type = (DataType) node.symbol.parent_symbol.node;
+                       return type;
+               }
+               return null;
+       }
+       
+       Symbol symbol_lookup_inherited (Symbol! sym, string! name) {
+               var result = sym.lookup (name);
+               if (result == null && sym.node is Class) {
+                       var cl = (Class) sym.node;
+                       for (cl = cl.base_class; cl != null && result == null; cl = cl.base_class) {
+                               result = cl.symbol.lookup (name);
                        }
-                       return result;
                }
+               return result;
+       }
 
-               public override void visit_parenthesized_expression (ParenthesizedExpression! expr) {
-                       expr.static_type = expr.inner.static_type;
-               }
+       public override void visit_parenthesized_expression (ParenthesizedExpression! expr) {
+               expr.static_type = expr.inner.static_type;
+       }
 
-               public override void visit_member_access (MemberAccess! expr) {
-                       Symbol base_symbol = null;
+       public override void visit_member_access (MemberAccess! expr) {
+               Symbol base_symbol = null;
 
-                       if (expr.inner == null) {
-                               base_symbol = current_symbol;
-                       
-                               var sym = current_symbol;
-                               while (sym != null && expr.symbol_reference == null) {
-                                       expr.symbol_reference = symbol_lookup_inherited (sym, expr.member_name);
-                                       sym = sym.parent_symbol;
-                               }
+               if (expr.inner == null) {
+                       base_symbol = current_symbol;
+               
+                       var sym = current_symbol;
+                       while (sym != null && expr.symbol_reference == null) {
+                               expr.symbol_reference = symbol_lookup_inherited (sym, expr.member_name);
+                               sym = sym.parent_symbol;
+                       }
 
-                               if (expr.symbol_reference == null) {
-                                       foreach (NamespaceReference ns in current_using_directives) {
-                                               var local_sym = ns.namespace_symbol.lookup (expr.member_name);
-                                               if (local_sym != null) {
-                                                       if (expr.symbol_reference != null) {
-                                                               Report.error (expr.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (expr.member_name, expr.symbol_reference.get_full_name (), local_sym.get_full_name ()));
-                                                               return;
-                                                       }
-                                                       expr.symbol_reference = local_sym;
+                       if (expr.symbol_reference == null) {
+                               foreach (NamespaceReference ns in current_using_directives) {
+                                       var local_sym = ns.namespace_symbol.lookup (expr.member_name);
+                                       if (local_sym != null) {
+                                               if (expr.symbol_reference != null) {
+                                                       Report.error (expr.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (expr.member_name, expr.symbol_reference.get_full_name (), local_sym.get_full_name ()));
+                                                       return;
                                                }
+                                               expr.symbol_reference = local_sym;
                                        }
                                }
-                       } else {
-                               if (expr.inner.error) {
-                                       /* if there was an error in the inner expression, skip this check */
-                                       return;
-                               }
-                       
-                               if (expr.inner is MemberAccess) {
-                                       var base = (MemberAccess) expr.inner;
-                                       base_symbol = base.symbol_reference;
-                                       if (base_symbol.node is Namespace ||
-                                           base_symbol.node is DataType) {
-                                               expr.symbol_reference = base_symbol.lookup (expr.member_name);
-                                       }
-                               }
-                               
-                               if (expr.symbol_reference == null && expr.inner.static_type != null) {
-                                       base_symbol = expr.inner.static_type.type.symbol;
-                                       expr.symbol_reference = symbol_lookup_inherited (base_symbol, expr.member_name);
-                               }
                        }
-                               
-                       if (expr.symbol_reference == null) {
-                               expr.error = true;
-                               Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, base_symbol.get_full_name ()));
+               } else {
+                       if (expr.inner.error) {
+                               /* if there was an error in the inner expression, skip this check */
                                return;
                        }
-                       
-                       current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE);
-
-                       expr.static_type = get_static_type_for_node (expr.symbol_reference.node);
-               }
-               
-               private bool is_type_compatible (TypeReference! expression_type, TypeReference! expected_type) {
-                       /* only null is compatible to null */
-                       if (expected_type.type == null && expected_type.type_parameter == null) {
-                               return (expression_type.type == null && expected_type.type_parameter == null);
-                       }
-
-                       /* null can be casted to any reference or array type */
-                       if (expression_type.type == null &&
-                           (expected_type.type_parameter != null ||
-                            expected_type.type.is_reference_type () ||
-                            expected_type.is_ref ||
-                            expected_type.array)) {
-                               return true;
-                       }
                
-                       /* temporarily ignore type parameters */
-                       if (expected_type.type_parameter != null) {
-                               return true;
-                       }
-                       
-                       if (expression_type.array != expected_type.array) {
-                               return false;
-                       }
-                       
-                       if (expression_type.type == expected_type.type) {
-                               return true;
-                       }
-                       
-                       /* int may be implicitly casted to long */
-                       if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("long").node) {
-                               return true;
-                       }
-                       
-                       /* int may be implicitly casted to uint */
-                       if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("uint").node) {
-                               return true;
+                       if (expr.inner is MemberAccess) {
+                               var base = (MemberAccess) expr.inner;
+                               base_symbol = base.symbol_reference;
+                               if (base_symbol.node is Namespace ||
+                                   base_symbol.node is DataType) {
+                                       expr.symbol_reference = base_symbol.lookup (expr.member_name);
+                               }
                        }
                        
-                       /* int may be implicitly casted to double */
-                       if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("double").node) {
-                               return true;
+                       if (expr.symbol_reference == null && expr.inner.static_type != null) {
+                               base_symbol = expr.inner.static_type.type.symbol;
+                               expr.symbol_reference = symbol_lookup_inherited (base_symbol, expr.member_name);
                        }
+               }
                        
-                       /* char may be implicitly casted to unichar */
-                       if (expression_type.type == root_symbol.lookup ("char").node && expected_type.type == root_symbol.lookup ("unichar").node) {
+               if (expr.symbol_reference == null) {
+                       expr.error = true;
+                       Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, base_symbol.get_full_name ()));
+                       return;
+               }
+               
+               current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE);
+
+               expr.static_type = get_static_type_for_node (expr.symbol_reference.node);
+       }
+       
+       private bool is_type_compatible (TypeReference! expression_type, TypeReference! expected_type) {
+               /* only null is compatible to null */
+               if (expected_type.type == null && expected_type.type_parameter == null) {
+                       return (expression_type.type == null && expected_type.type_parameter == null);
+               }
+
+               /* null can be casted to any reference or array type */
+               if (expression_type.type == null &&
+                   (expected_type.type_parameter != null ||
+                    expected_type.type.is_reference_type () ||
+                    expected_type.is_ref ||
+                    expected_type.array)) {
+                       return true;
+               }
+       
+               /* temporarily ignore type parameters */
+               if (expected_type.type_parameter != null) {
+                       return true;
+               }
+               
+               if (expression_type.array != expected_type.array) {
+                       return false;
+               }
+               
+               if (expression_type.type == expected_type.type) {
+                       return true;
+               }
+               
+               /* int may be implicitly casted to long */
+               if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("long").node) {
+                       return true;
+               }
+               
+               /* int may be implicitly casted to uint */
+               if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("uint").node) {
+                       return true;
+               }
+               
+               /* int may be implicitly casted to double */
+               if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("double").node) {
+                       return true;
+               }
+               
+               /* char may be implicitly casted to unichar */
+               if (expression_type.type == root_symbol.lookup ("char").node && expected_type.type == root_symbol.lookup ("unichar").node) {
+                       return true;
+               }
+               
+               /* non-class types must match exactly */
+               if (!(expression_type.type is Class)) {
+                       return false;
+               }
+               
+               var cl = (Class) expression_type.type;
+               
+               var base_class = cl.base_class;
+               for (; base_class != null; base_class = base_class.base_class) {
+                       if (base_class == expected_type.type) {
                                return true;
                        }
-                       
-                       /* non-class types must match exactly */
-                       if (!(expression_type.type is Class)) {
-                               return false;
-                       }
-                       
-                       var cl = (Class) expression_type.type;
-                       
-                       var base_class = cl.base_class;
-                       for (; base_class != null; base_class = base_class.base_class) {
-                               if (base_class == expected_type.type) {
-                                       return true;
-                               }
-                       }
-                       
-                       return false;
                }
+               
+               return false;
+       }
 
-               public override void visit_begin_invocation_expression (InvocationExpression! expr) {
-                       if (expr.call.error) {
-                               /* if method resolving didn't succeed, skip this check */
+       public override void visit_begin_invocation_expression (InvocationExpression! expr) {
+               if (expr.call.error) {
+                       /* if method resolving didn't succeed, skip this check */
+                       expr.error = true;
+                       return;
+               }
+               
+               var msym = expr.call.symbol_reference;
+               
+               List<FormalParameter> params;
+               
+               if (msym.node is VariableDeclarator) {
+                       var decl = (VariableDeclarator) msym.node;
+                       if (decl.type_reference.type is Callback) {
+                               var cb = (Callback) decl.type_reference.type;
+                               params = cb.get_parameters ();
+                       } else {
                                expr.error = true;
+                               Report.error (expr.source_reference, "invocation not supported in this context");
                                return;
                        }
-                       
-                       var msym = expr.call.symbol_reference;
-                       
-                       List<FormalParameter> params;
-                       
-                       if (msym.node is VariableDeclarator) {
-                               var decl = (VariableDeclarator) msym.node;
-                               if (decl.type_reference.type is Callback) {
-                                       var cb = (Callback) decl.type_reference.type;
-                                       params = cb.get_parameters ();
-                               } else {
-                                       expr.error = true;
-                                       Report.error (expr.source_reference, "invocation not supported in this context");
-                                       return;
-                               }
-                       } else if (msym.node is FormalParameter) {
-                               var param = (FormalParameter) msym.node;
-                               if (param.type_reference.type is Callback) {
-                                       var cb = (Callback) param.type_reference.type;
-                                       params = cb.get_parameters ();
-                               } else {
-                                       expr.error = true;
-                                       Report.error (expr.source_reference, "invocation not supported in this context");
-                                       return;
-                               }
-                       } else if (msym.node is Method) {
-                               var m = (Method) msym.node;
-                               params = m.parameters;
+               } else if (msym.node is FormalParameter) {
+                       var param = (FormalParameter) msym.node;
+                       if (param.type_reference.type is Callback) {
+                               var cb = (Callback) param.type_reference.type;
+                               params = cb.get_parameters ();
                        } else {
                                expr.error = true;
                                Report.error (expr.source_reference, "invocation not supported in this context");
                                return;
                        }
-               
-                       List arg_it = expr.argument_list;
-                       foreach (FormalParameter param in params) {
-                               if (param.ellipsis) {
-                                       break;
-                               }
-                               
-                               if (arg_it != null) {
-                                       var arg = (Expression) arg_it.data;
+               } else if (msym.node is Method) {
+                       var m = (Method) msym.node;
+                       params = m.parameters;
+               } else {
+                       expr.error = true;
+                       Report.error (expr.source_reference, "invocation not supported in this context");
+                       return;
+               }
+       
+               List arg_it = expr.argument_list;
+               foreach (FormalParameter param in params) {
+                       if (param.ellipsis) {
+                               break;
+                       }
+                       
+                       if (arg_it != null) {
+                               var arg = (Expression) arg_it.data;
 
-                                       /* store expected type for callback parameters */
-                                       arg.expected_type = param.type_reference;
-                                       
-                                       arg_it = arg_it.next;
-                               }
+                               /* store expected type for callback parameters */
+                               arg.expected_type = param.type_reference;
+                               
+                               arg_it = arg_it.next;
                        }
                }
+       }
 
-               public override void visit_end_invocation_expression (InvocationExpression! expr) {
-                       if (expr.error) {
-                               return;
+       public override void visit_end_invocation_expression (InvocationExpression! expr) {
+               if (expr.error) {
+                       return;
+               }
+               
+               var msym = expr.call.symbol_reference;
+               
+               TypeReference ret_type;
+               List<FormalParameter> params;
+               
+               if (msym.node is VariableDeclarator) {
+                       var decl = (VariableDeclarator) msym.node;
+                       var cb = (Callback) decl.type_reference.type;
+                       ret_type = cb.return_type;
+                       params = cb.get_parameters ();
+               } else if (msym.node is FormalParameter) {
+                       var param = (FormalParameter) msym.node;
+                       var cb = (Callback) param.type_reference.type;
+                       ret_type = cb.return_type;
+                       params = cb.get_parameters ();
+               } else if (msym.node is Method) {
+                       var m = (Method) msym.node;
+                       ret_type = m.return_type;
+                       params = m.parameters;
+               }
+       
+               expr.static_type = ret_type;
+               
+               List arg_it = expr.argument_list;
+               
+               bool ellipsis = false;
+               int i = 0;
+               foreach (FormalParameter param in params) {
+                       if (param.ellipsis) {
+                               ellipsis = true;
+                               break;
                        }
-                       
-                       var msym = expr.call.symbol_reference;
-                       
-                       TypeReference ret_type;
-                       List<FormalParameter> params;
-                       
-                       if (msym.node is VariableDeclarator) {
-                               var decl = (VariableDeclarator) msym.node;
-                               var cb = (Callback) decl.type_reference.type;
-                               ret_type = cb.return_type;
-                               params = cb.get_parameters ();
-                       } else if (msym.node is FormalParameter) {
-                               var param = (FormalParameter) msym.node;
-                               var cb = (Callback) param.type_reference.type;
-                               ret_type = cb.return_type;
-                               params = cb.get_parameters ();
-                       } else if (msym.node is Method) {
-                               var m = (Method) msym.node;
-                               ret_type = m.return_type;
-                               params = m.parameters;
+
+                       /* header file necessary if we need to cast argument */
+                       if (param.type_reference.type != null) {
+                               current_source_file.add_symbol_dependency (param.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
                        }
-               
-                       expr.static_type = ret_type;
-                       
-                       List arg_it = expr.argument_list;
-                       
-                       bool ellipsis = false;
-                       int i = 0;
-                       foreach (FormalParameter param in params) {
-                               if (param.ellipsis) {
-                                       ellipsis = true;
-                                       break;
-                               }
 
-                               /* header file necessary if we need to cast argument */
-                               if (param.type_reference.type != null) {
-                                       current_source_file.add_symbol_dependency (param.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+                       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 ()));
+                                       return;
                                }
-
-                               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 ()));
-                                               return;
-                                       }
-                               } else {
-                                       var arg = (Expression) arg_it.data;
-                                       if (arg.static_type != null && !is_type_compatible (arg.static_type, param.type_reference)) {
-                                               /* if there was an error in the argument,
-                                                * i.e. arg.static_type == null, skip type check */
-                                               Report.error (expr.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.static_type.to_string (), param.type_reference.to_string ()));
-                                               return;
-                                       }
-                                       
-                                       arg_it = arg_it.next;
-
-                                       i++;
+                       } else {
+                               var arg = (Expression) arg_it.data;
+                               if (arg.static_type != null && !is_type_compatible (arg.static_type, param.type_reference)) {
+                                       /* if there was an error in the argument,
+                                        * i.e. arg.static_type == null, skip type check */
+                                       Report.error (expr.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.static_type.to_string (), param.type_reference.to_string ()));
+                                       return;
                                }
-                       }
-                       
-                       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 ()));
-                               return;
-                       }
-               }
+                               
+                               arg_it = arg_it.next;
 
-               public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
-                       if (expr.type_reference.type == null) {
-                               /* if type resolving didn't succeed, skip this check */
-                               return;
+                               i++;
                        }
+               }
                
-                       current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+               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 ()));
+                       return;
+               }
+       }
 
-                       expr.static_type = expr.type_reference.copy ();
-                       expr.static_type.is_ref = true;
-                       
-                       var cl = (Class) expr.type_reference.type;
-                       while (cl != null) {
-                               if (cl == initially_unowned_type) {
-                                       expr.static_type.floating_reference = true;
-                                       break;
-                               }
-                       
-                               cl = cl.base_class;
-                       }
+       public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
+               if (expr.type_reference.type == null) {
+                       /* if type resolving didn't succeed, skip this check */
+                       return;
                }
+       
+               current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
 
-               public override void visit_unary_expression (UnaryExpression! expr) {
-                       if (expr.inner.static_type == null) {
-                               /* if there was an error in the inner expression, skip type check */
-                               return;
+               expr.static_type = expr.type_reference.copy ();
+               expr.static_type.is_ref = true;
+               
+               var cl = (Class) expr.type_reference.type;
+               while (cl != null) {
+                       if (cl == initially_unowned_type) {
+                               expr.static_type.floating_reference = true;
+                               break;
                        }
                
-                       if (expr.operator == UnaryOperator.PLUS || expr.operator == UnaryOperator.MINUS) {
-                               // integer or floating point type
+                       cl = cl.base_class;
+               }
+       }
 
-                               expr.static_type = expr.inner.static_type;
-                       } else if (expr.operator == UnaryOperator.LOGICAL_NEGATION) {
-                               // boolean type
+       public override void visit_unary_expression (UnaryExpression! expr) {
+               if (expr.inner.static_type == null) {
+                       /* if there was an error in the inner expression, skip type check */
+                       return;
+               }
+       
+               if (expr.operator == UnaryOperator.PLUS || expr.operator == UnaryOperator.MINUS) {
+                       // integer or floating point type
 
-                               expr.static_type = expr.inner.static_type;
-                       } else if (expr.operator == UnaryOperator.BITWISE_COMPLEMENT) {
-                               // integer type
+                       expr.static_type = expr.inner.static_type;
+               } else if (expr.operator == UnaryOperator.LOGICAL_NEGATION) {
+                       // boolean type
 
-                               expr.static_type = expr.inner.static_type;
-                       } else if (expr.operator == UnaryOperator.REF) {
-                               // value type
+                       expr.static_type = expr.inner.static_type;
+               } else if (expr.operator == UnaryOperator.BITWISE_COMPLEMENT) {
+                       // integer type
 
-                               expr.static_type = expr.inner.static_type;
-                       } else if (expr.operator == UnaryOperator.OUT) {
-                               // reference type
+                       expr.static_type = expr.inner.static_type;
+               } else if (expr.operator == UnaryOperator.REF) {
+                       // value type
 
-                               expr.static_type = expr.inner.static_type;
-                       } else {
-                               assert_not_reached ();
-                       }
+                       expr.static_type = expr.inner.static_type;
+               } else if (expr.operator == UnaryOperator.OUT) {
+                       // reference type
+
+                       expr.static_type = expr.inner.static_type;
+               } else {
+                       assert_not_reached ();
                }
+       }
 
-               public override void visit_cast_expression (CastExpression! expr) {
-                       if (expr.type_reference.type == null) {
-                               /* if type resolving didn't succeed, skip this check */
-                               return;
-                       }
-               
-                       current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+       public override void visit_cast_expression (CastExpression! expr) {
+               if (expr.type_reference.type == null) {
+                       /* if type resolving didn't succeed, skip this check */
+                       return;
+               }
+       
+               current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
 
-                       expr.static_type = expr.type_reference;
+               expr.static_type = expr.type_reference;
+       }
+       
+       private bool check_binary_type (BinaryExpression! expr, string! operation) {
+               if (!is_type_compatible (expr.right.static_type, expr.left.static_type)) {
+                       Report.error (expr.source_reference, "%s: Cannot convert from `%s' to `%s'".printf (operation, expr.right.static_type.to_string (), expr.left.static_type.to_string ()));
+                       return false;
                }
                
-               private bool check_binary_type (BinaryExpression! expr, string! operation) {
-                       if (!is_type_compatible (expr.right.static_type, expr.left.static_type)) {
-                               Report.error (expr.source_reference, "%s: Cannot convert from `%s' to `%s'".printf (operation, expr.right.static_type.to_string (), expr.left.static_type.to_string ()));
-                               return false;
-                       }
-                       
-                       return true;
+               return true;
+       }
+       
+       public override void visit_binary_expression (BinaryExpression! expr) {
+               if (expr.left.static_type == null
+                   || expr.right.static_type == null) {
+                       /* if there were any errors in inner expressions, skip type check */
+                       return;
                }
-               
-               public override void visit_binary_expression (BinaryExpression! expr) {
-                       if (expr.left.static_type == null
-                           || expr.right.static_type == null) {
-                               /* if there were any errors in inner expressions, skip type check */
+       
+               if (expr.left.static_type.type == string_type.type
+                   && expr.operator == BinaryOperator.PLUS) {
+                       if (expr.right.static_type.type != string_type.type) {
+                               Report.error (expr.source_reference, "Operands must be strings");
+                       }
+
+                       expr.static_type = string_type;
+               } else if (expr.operator == BinaryOperator.PLUS
+                          || expr.operator == BinaryOperator.MINUS
+                          || expr.operator == BinaryOperator.MUL
+                          || expr.operator == BinaryOperator.DIV) {
+                       // TODO: check for integer or floating point type in expr.left
+
+                       if (!check_binary_type (expr, "Arithmetic operation")) {
                                return;
                        }
-               
-                       if (expr.left.static_type.type == string_type.type
-                           && expr.operator == BinaryOperator.PLUS) {
-                               if (expr.right.static_type.type != string_type.type) {
-                                       Report.error (expr.source_reference, "Operands must be strings");
-                               }
 
-                               expr.static_type = string_type;
-                       } else if (expr.operator == BinaryOperator.PLUS
-                                  || expr.operator == BinaryOperator.MINUS
-                                  || expr.operator == BinaryOperator.MUL
-                                  || expr.operator == BinaryOperator.DIV) {
-                               // TODO: check for integer or floating point type in expr.left
+                       expr.static_type = expr.left.static_type;
+               } else if (expr.operator == BinaryOperator.MOD
+                          || expr.operator == BinaryOperator.SHIFT_LEFT
+                          || expr.operator == BinaryOperator.SHIFT_RIGHT
+                          || expr.operator == BinaryOperator.BITWISE_XOR) {
+                       // TODO: check for integer type in expr.left
 
-                               if (!check_binary_type (expr, "Arithmetic operation")) {
-                                       return;
-                               }
+                       if (!check_binary_type (expr, "Arithmetic operation")) {
+                               return;
+                       }
 
-                               expr.static_type = expr.left.static_type;
-                       } else if (expr.operator == BinaryOperator.MOD
-                                  || expr.operator == BinaryOperator.SHIFT_LEFT
-                                  || expr.operator == BinaryOperator.SHIFT_RIGHT
-                                  || expr.operator == BinaryOperator.BITWISE_XOR) {
-                               // TODO: check for integer type in expr.left
+                       expr.static_type = expr.left.static_type;
+               } else if (expr.operator == BinaryOperator.LESS_THAN
+                          || expr.operator == BinaryOperator.GREATER_THAN
+                          || expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL
+                          || expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
+                       if (expr.left.static_type.type == string_type.type
+                           && expr.right.static_type.type == string_type.type) {
+                               /* string comparison: convert to a.collate (b) OP 0 */
+                               
+                               var cmp_call = new InvocationExpression (call = new MemberAccess (inner = expr.left, member_name = "collate"));
+                               cmp_call.add_argument (expr.right);
+                               expr.left = cmp_call;
+                               
+                               expr.right = new LiteralExpression (literal = new IntegerLiteral (value = "0"));
+                               
+                               expr.left.accept (this);
+                       } else {
+                               /* TODO: check for integer or floating point type in expr.left */
 
-                               if (!check_binary_type (expr, "Arithmetic operation")) {
+                               if (!check_binary_type (expr, "Relational operation")) {
                                        return;
                                }
+                       }
+                       
+                       expr.static_type = bool_type;
+               } else if (expr.operator == BinaryOperator.EQUALITY
+                          || expr.operator == BinaryOperator.INEQUALITY) {
+                       /* relational operation */
 
-                               expr.static_type = expr.left.static_type;
-                       } else if (expr.operator == BinaryOperator.LESS_THAN
-                                  || expr.operator == BinaryOperator.GREATER_THAN
-                                  || expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL
-                                  || expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
-                               if (expr.left.static_type.type == string_type.type
-                                   && expr.right.static_type.type == string_type.type) {
-                                       /* string comparison: convert to a.collate (b) OP 0 */
-                                       
-                                       var cmp_call = new InvocationExpression (call = new MemberAccess (inner = expr.left, member_name = "collate"));
-                                       cmp_call.add_argument (expr.right);
-                                       expr.left = cmp_call;
-                                       
-                                       expr.right = new LiteralExpression (literal = new IntegerLiteral (value = "0"));
-                                       
-                                       expr.left.accept (this);
-                               } else {
-                                       /* TODO: check for integer or floating point type in expr.left */
-
-                                       if (!check_binary_type (expr, "Relational operation")) {
-                                               return;
-                                       }
-                               }
+                       if (!is_type_compatible (expr.right.static_type, expr.left.static_type)
+                           && !is_type_compatible (expr.left.static_type, expr.right.static_type)) {
+                               Report.error (expr.source_reference, "Equality operation: `%s' and `%s' are incompatible, comparison would always evaluate to false".printf (expr.right.static_type.to_string (), expr.left.static_type.to_string ()));
+                               return;
+                       }
+                       
+                       if (expr.left.static_type.type == string_type.type
+                           && expr.right.static_type.type == string_type.type) {
+                               /* string comparison: convert to a.collate (b) OP 0 */
                                
-                               expr.static_type = bool_type;
-                       } else if (expr.operator == BinaryOperator.EQUALITY
-                                  || expr.operator == BinaryOperator.INEQUALITY) {
-                               /* relational operation */
-
-                               if (!is_type_compatible (expr.right.static_type, expr.left.static_type)
-                                   && !is_type_compatible (expr.left.static_type, expr.right.static_type)) {
-                                       Report.error (expr.source_reference, "Equality operation: `%s' and `%s' are incompatible, comparison would always evaluate to false".printf (expr.right.static_type.to_string (), expr.left.static_type.to_string ()));
-                                       return;
-                               }
+                               var cmp_call = new InvocationExpression (call = new MemberAccess (inner = expr.left, member_name = "collate"));
+                               cmp_call.add_argument (expr.right);
+                               expr.left = cmp_call;
                                
-                               if (expr.left.static_type.type == string_type.type
-                                   && expr.right.static_type.type == string_type.type) {
-                                       /* string comparison: convert to a.collate (b) OP 0 */
-                                       
-                                       var cmp_call = new InvocationExpression (call = new MemberAccess (inner = expr.left, member_name = "collate"));
-                                       cmp_call.add_argument (expr.right);
-                                       expr.left = cmp_call;
-                                       
-                                       expr.right = new LiteralExpression (literal = new IntegerLiteral (value = "0"));
-                                       
-                                       expr.left.accept (this);
-                               }
+                               expr.right = new LiteralExpression (literal = new IntegerLiteral (value = "0"));
+                               
+                               expr.left.accept (this);
+                       }
 
-                               expr.static_type = bool_type;
-                       } else if (expr.operator == BinaryOperator.BITWISE_AND
-                                  || expr.operator == BinaryOperator.BITWISE_OR) {
-                               // integer type or flags type
+                       expr.static_type = bool_type;
+               } else if (expr.operator == BinaryOperator.BITWISE_AND
+                          || expr.operator == BinaryOperator.BITWISE_OR) {
+                       // integer type or flags type
+
+                       expr.static_type = expr.left.static_type;
+               } else if (expr.operator == BinaryOperator.AND
+                          || expr.operator == BinaryOperator.OR) {
+                       if (expr.left.static_type.type != bool_type.type || expr.right.static_type.type != bool_type.type) {
+                               Report.error (expr.source_reference, "Operands must be boolean");
+                       }
 
-                               expr.static_type = expr.left.static_type;
-                       } else if (expr.operator == BinaryOperator.AND
-                                  || expr.operator == BinaryOperator.OR) {
-                               if (expr.left.static_type.type != bool_type.type || expr.right.static_type.type != bool_type.type) {
-                                       Report.error (expr.source_reference, "Operands must be boolean");
-                               }
+                       expr.static_type = bool_type;
+               } else {
+                       assert_not_reached ();
+               }
+       }
 
-                               expr.static_type = bool_type;
-                       } else {
-                               assert_not_reached ();
-                       }
+       public override void visit_type_check (TypeCheck! expr) {
+               if (expr.type_reference.type == null) {
+                       /* if type resolving didn't succeed, skip this check */
+                       return;
                }
+       
+               current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
 
-               public override void visit_type_check (TypeCheck! expr) {
-                       if (expr.type_reference.type == null) {
-                               /* if type resolving didn't succeed, skip this check */
-                               return;
-                       }
-               
-                       current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+               expr.static_type = bool_type;
+       }
 
-                       expr.static_type = bool_type;
+       public override void visit_conditional_expression (ConditionalExpression! expr) {
+               if (expr.condition.static_type.type != bool_type.type) {
+                       expr.error = true;
+                       Report.error (expr.condition.source_reference, "Condition must be boolean");
+                       return;
                }
                
-               private ref string get_lambda_name () {
-                       var result = "__lambda%d".printf (next_lambda_id);
+               /* FIXME: use greatest lower bound in the type hierarchy */
+               expr.static_type = expr.true_expression.static_type;
+       }
+       
+       private ref string get_lambda_name () {
+               var result = "__lambda%d".printf (next_lambda_id);
 
-                       next_lambda_id++;
-                       
-                       return result;
-               }
+               next_lambda_id++;
                
-               private Method find_current_method () {
-                       var sym = current_symbol;
-                       while (sym != null) {
-                               if (sym.node is Method) {
-                                       return (Method) sym.node;
-                               }
-                               sym = sym.parent_symbol;
+               return result;
+       }
+       
+       private Method find_current_method () {
+               var sym = current_symbol;
+               while (sym != null) {
+                       if (sym.node is Method) {
+                               return (Method) sym.node;
                        }
-                       return null;
+                       sym = sym.parent_symbol;
                }
+               return null;
+       }
 
-               public override void visit_begin_lambda_expression (LambdaExpression! l) {
-                       if (l.expected_type == null || !(l.expected_type.type is Callback)) {
-                               l.error = true;
-                               Report.error (l.source_reference, "lambda expression not allowed in this context");
-                               return;
-                       }
-                       
-                       var current_method = find_current_method ();
-                       
-                       var cb = (Callback) l.expected_type.type;
-                       l.method = new Method (name = get_lambda_name (), return_type = cb.return_type);
-                       l.method.instance = cb.instance && current_method.instance;
-                       l.method.symbol = new Symbol (node = l.method);
-                       l.method.symbol.parent_symbol = current_symbol;
-                       
-                       var lambda_params = l.get_parameters ();
-                       var lambda_param_it = lambda_params;
-                       foreach (FormalParameter cb_param in cb.get_parameters ()) {
-                               if (lambda_param_it == null) {
-                                       /* lambda expressions are allowed to have less parameters */
-                                       break;
-                               }
-                               
-                               var lambda_param = (string) lambda_param_it.data;
-                               
-                               var param = new FormalParameter (name = lambda_param);
-                               param.type_reference = cb_param.type_reference;
-                               param.symbol = new Symbol (node = param);
-                               l.method.symbol.add (param.name, param.symbol);
-                               
-                               l.method.add_parameter (param);
-                               
-                               lambda_param_it = lambda_param_it.next;
+       public override void visit_begin_lambda_expression (LambdaExpression! l) {
+               if (l.expected_type == null || !(l.expected_type.type is Callback)) {
+                       l.error = true;
+                       Report.error (l.source_reference, "lambda expression not allowed in this context");
+                       return;
+               }
+               
+               var current_method = find_current_method ();
+               
+               var cb = (Callback) l.expected_type.type;
+               l.method = new Method (name = get_lambda_name (), return_type = cb.return_type);
+               l.method.instance = cb.instance && current_method.instance;
+               l.method.symbol = new Symbol (node = l.method);
+               l.method.symbol.parent_symbol = current_symbol;
+               
+               var lambda_params = l.get_parameters ();
+               var lambda_param_it = lambda_params;
+               foreach (FormalParameter cb_param in cb.get_parameters ()) {
+                       if (lambda_param_it == null) {
+                               /* lambda expressions are allowed to have less parameters */
+                               break;
                        }
                        
-                       if (lambda_param_it != null) {
-                               /* lambda expressions may not expect more parameters */
-                               l.error = true;
-                               Report.error (l.source_reference, "lambda expression: too many parameters");
-                               return;
-                       }
+                       var lambda_param = (string) lambda_param_it.data;
                        
-                       var block = new Block ();
-                       block.symbol = new Symbol (node = block);
-                       block.symbol.parent_symbol = l.method.symbol;
-                       if (l.method.return_type.type != null) {
-                               block.add_statement (new ReturnStatement (return_expression = l.inner));
-                       } else {
-                               block.add_statement (new ExpressionStatement (expression = l.inner));
-                       }
+                       var param = new FormalParameter (name = lambda_param);
+                       param.type_reference = cb_param.type_reference;
+                       param.symbol = new Symbol (node = param);
+                       l.method.symbol.add (param.name, param.symbol);
                        
-                       l.method.body = block;
+                       l.method.add_parameter (param);
                        
-                       /* lambda expressions should be usable like MemberAccess of a method */
-                       l.symbol_reference = l.method.symbol;
+                       lambda_param_it = lambda_param_it.next;
+               }
+               
+               if (lambda_param_it != null) {
+                       /* lambda expressions may not expect more parameters */
+                       l.error = true;
+                       Report.error (l.source_reference, "lambda expression: too many parameters");
+                       return;
+               }
+               
+               var block = new Block ();
+               block.symbol = new Symbol (node = block);
+               block.symbol.parent_symbol = l.method.symbol;
+               if (l.method.return_type.type != null) {
+                       block.add_statement (new ReturnStatement (return_expression = l.inner));
+               } else {
+                       block.add_statement (new ExpressionStatement (expression = l.inner));
                }
+               
+               l.method.body = block;
+               
+               /* lambda expressions should be usable like MemberAccess of a method */
+               l.symbol_reference = l.method.symbol;
+       }
 
-               public override void visit_begin_assignment (Assignment! a) {
-                       var ma = (MemberAccess) a.left;
-                       
-                       if (ma.symbol_reference.node is Signal) {
-                               var sig = (Signal) ma.symbol_reference.node;
+       public override void visit_begin_assignment (Assignment! a) {
+               var ma = (MemberAccess) a.left;
+               
+               if (ma.symbol_reference.node is Signal) {
+                       var sig = (Signal) ma.symbol_reference.node;
 
-                               a.right.expected_type = new TypeReference ();
-                               a.right.expected_type.type = sig.get_callback ();
-                       }
+                       a.right.expected_type = new TypeReference ();
+                       a.right.expected_type.type = sig.get_callback ();
                }
+       }
 
-               public override void visit_end_assignment (Assignment! a) {
-                       if (!(a.left is MemberAccess)) {
-                               a.error = true;
-                               Report.error (a.source_reference, "unsupported lvalue in assignment");
-                               return;
-                       }
+       public override void visit_end_assignment (Assignment! a) {
+               if (!(a.left is MemberAccess)) {
+                       a.error = true;
+                       Report.error (a.source_reference, "unsupported lvalue in assignment");
+                       return;
+               }
+       
+               var ma = (MemberAccess) a.left;
                
-                       var ma = (MemberAccess) a.left;
+               if (ma.symbol_reference.node is Signal) {
+                       var sig = (Signal) ma.symbol_reference.node;
+               } 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) {
+                       var decl = (VariableDeclarator) ma.symbol_reference.node;
                        
-                       if (ma.symbol_reference.node is Signal) {
-                               var sig = (Signal) ma.symbol_reference.node;
-                       } 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) {
-                               var decl = (VariableDeclarator) ma.symbol_reference.node;
+                       var right_ma = (MemberAccess) a.right;
+                       if (right_ma.symbol_reference.node is Method &&
+                           decl.type_reference.type is Callback) {
+                               var m = (Method) right_ma.symbol_reference.node;
+                               var cb = (Callback) decl.type_reference.type;
                                
-                               var right_ma = (MemberAccess) a.right;
-                               if (right_ma.symbol_reference.node is Method &&
-                                   decl.type_reference.type is Callback) {
-                                       var m = (Method) right_ma.symbol_reference.node;
-                                       var cb = (Callback) decl.type_reference.type;
-                                       
-                                       /* check whether method matches callback type */
-                                       if (!cb.matches_method (m)) {
-                                               decl.error = true;
-                                               Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.symbol.get_full_name (), cb.symbol.get_full_name ()));
-                                               return;
-                                       }
-                                       
-                                       a.right.static_type = decl.type_reference;
-                               } else {
-                                       a.error = true;
-                                       Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt");
-                                       return;
-                               }
-                       } else if (a.left.static_type != null && a.right.static_type != null) {
-                               if (!is_type_compatible (a.right.static_type, a.left.static_type)) {
-                                       /* if there was an error on either side,
-                                        * i.e. a.{left|right}.static_type == null, skip type check */
-                                       Report.error (a.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (a.right.static_type.to_string (), a.left.static_type.to_string ()));
+                               /* check whether method matches callback type */
+                               if (!cb.matches_method (m)) {
+                                       decl.error = true;
+                                       Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.symbol.get_full_name (), cb.symbol.get_full_name ()));
                                        return;
                                }
                                
-                               if (memory_management) {
-                                       if (a.right.static_type.is_ref) {
-                                               /* rhs transfers ownership of the expression */
-                                               if (!a.left.static_type.is_lvalue_ref) {
-                                                       /* lhs doesn't own the value
-                                                        * promote lhs type if it is a local variable
-                                                        * error if it's not a local variable */
-                                                       if (!(ma.symbol_reference.node is VariableDeclarator)) {
-                                                               Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
-                                                       }
-                                                       
-                                                       a.left.static_type.is_lvalue_ref = true;
+                               a.right.static_type = decl.type_reference;
+                       } else {
+                               a.error = true;
+                               Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt");
+                               return;
+                       }
+               } else if (a.left.static_type != null && a.right.static_type != null) {
+                       if (!is_type_compatible (a.right.static_type, a.left.static_type)) {
+                               /* if there was an error on either side,
+                                * i.e. a.{left|right}.static_type == null, skip type check */
+                               Report.error (a.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (a.right.static_type.to_string (), a.left.static_type.to_string ()));
+                               return;
+                       }
+                       
+                       if (memory_management) {
+                               if (a.right.static_type.is_ref) {
+                                       /* rhs transfers ownership of the expression */
+                                       if (!a.left.static_type.is_lvalue_ref) {
+                                               /* lhs doesn't own the value
+                                                * promote lhs type if it is a local variable
+                                                * error if it's not a local variable */
+                                               if (!(ma.symbol_reference.node is VariableDeclarator)) {
+                                                       Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
                                                }
-                                       } else if (a.left.static_type.is_lvalue_ref) {
-                                               /* lhs wants to own the value
-                                                * rhs doesn't transfer the ownership
-                                                * code generator needs to add reference
-                                                * increment calls */
+                                               
+                                               a.left.static_type.is_lvalue_ref = true;
                                        }
+                               } else if (a.left.static_type.is_lvalue_ref) {
+                                       /* lhs wants to own the value
+                                        * rhs doesn't transfer the ownership
+                                        * code generator needs to add reference
+                                        * increment calls */
                                }
                        }
-                       
-                       a.static_type = a.left.static_type;
                }
+               
+               a.static_type = a.left.static_type;
        }
 }
index 187275d..32302ee 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class SymbolBuilder : CodeVisitor {
-               Symbol root;
-               Symbol current_type;
-               Symbol current_symbol;
-               
-               public void build (CodeContext! context) {
-                       root = context.get_root ();
-                       context.accept (this);
+/**
+ * Code visitor building the symbol tree.
+ */
+public class Vala.SymbolBuilder : CodeVisitor {
+       Symbol root;
+       Symbol current_type;
+       Symbol current_symbol;
+       
+       /**
+        * Build the symbol tree for the specified code context.
+        *
+        * @param context a code context
+        */
+       public void build (CodeContext! context) {
+               root = context.get_root ();
+               context.accept (this);
+       }
+       
+       public override void visit_begin_namespace (Namespace! ns) {
+               if (ns.name == null) {
+                       ns.symbol = root;
                }
                
-               public override void visit_begin_namespace (Namespace! ns) {
-                       if (ns.name == null) {
-                               ns.symbol = root;
-                       }
-                       
-                       if (ns.symbol == null) {
-                               ns.symbol = root.lookup (ns.name);
-                       }
-                       if (ns.symbol == null) {
-                               ns.symbol = new Symbol (node = ns);
-                               root.add (ns.name, ns.symbol);
-                       }
-                       
-                       current_symbol = ns.symbol;
+               if (ns.symbol == null) {
+                       ns.symbol = root.lookup (ns.name);
                }
-               
-               public override void visit_end_namespace (Namespace! ns) {
-                       current_symbol = current_symbol.parent_symbol;
+               if (ns.symbol == null) {
+                       ns.symbol = new Symbol (node = ns);
+                       root.add (ns.name, ns.symbol);
                }
                
-               private Symbol add_symbol (string! name, CodeNode! node) {
-                       if (current_symbol.lookup (name) != null) {
-                               node.error = true;
-                               Report.error (node.source_reference, "`%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), name));
-                               return null;
-                       }
-                       node.symbol = new Symbol (node = node);
-                       current_symbol.add (name, node.symbol);
-                       
-                       return node.symbol;
-               }
+               current_symbol = ns.symbol;
+       }
        
-               public override void visit_begin_class (Class! cl) {
-                       if (add_symbol (cl.name, cl) == null) {
-                               return;
-                       }
-                       
-                       current_symbol = cl.symbol;
-               }
-               
-               public override void visit_end_class (Class! cl) {
-                       if (cl.error) {
-                               /* skip classes with errors */
-                               return;
-                       }
-                       
-                       current_symbol = current_symbol.parent_symbol;
-               }
+       public override void visit_end_namespace (Namespace! ns) {
+               current_symbol = current_symbol.parent_symbol;
+       }
+       
+       private Symbol add_symbol (string! name, CodeNode! node) {
+               if (current_symbol.lookup (name) != null) {
+                       node.error = true;
+                       Report.error (node.source_reference, "`%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), name));
+                       return null;
+               }
+               node.symbol = new Symbol (node = node);
+               current_symbol.add (name, node.symbol);
                
-               public override void visit_begin_struct (Struct! st) {
-                       if (add_symbol (st.name, st) == null) {
-                               return;
-                       }
-                       
-                       current_symbol = st.symbol;
+               return node.symbol;
+       }
+
+       public override void visit_begin_class (Class! cl) {
+               if (add_symbol (cl.name, cl) == null) {
+                       return;
                }
                
-               public override void visit_end_struct (Struct! st) {
-                       if (st.error) {
-                               /* skip structs with errors */
-                               return;
-                       }
-                       
-                       current_symbol = current_symbol.parent_symbol;
-               }
+               current_symbol = cl.symbol;
+       }
        
-               public override void visit_begin_interface (Interface! iface) {
-                       if (add_symbol (iface.name, iface) == null) {
-                               return;
-                       }
-                       
-                       current_symbol = iface.symbol;
+       public override void visit_end_class (Class! cl) {
+               if (cl.error) {
+                       /* skip classes with errors */
+                       return;
                }
                
-               public override void visit_end_interface (Interface! iface) {
-                       if (iface.error) {
-                               /* skip interfaces with errors */
-                               return;
-                       }
-                       
-                       current_symbol = current_symbol.parent_symbol;
+               current_symbol = current_symbol.parent_symbol;
+       }
+       
+       public override void visit_begin_struct (Struct! st) {
+               if (add_symbol (st.name, st) == null) {
+                       return;
                }
                
-               public override void visit_begin_enum (Enum! en) {
-                       if (add_symbol (en.name, en) == null) {
-                               return;
-                       }
-                       
-                       current_symbol = en.symbol;
+               current_symbol = st.symbol;
+       }
+       
+       public override void visit_end_struct (Struct! st) {
+               if (st.error) {
+                       /* skip structs with errors */
+                       return;
                }
                
-               public override void visit_end_enum (Enum! en) {
-                       if (en.error) {
-                               /* skip enums with errors */
-                               return;
-                       }
-                       
-                       current_symbol = current_symbol.parent_symbol;
-               }
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_enum_value (EnumValue! ev) {
-                       ev.symbol = new Symbol (node = ev);
-                       current_symbol.add (ev.name, ev.symbol);
+       public override void visit_begin_interface (Interface! iface) {
+               if (add_symbol (iface.name, iface) == null) {
+                       return;
                }
                
-               public override void visit_begin_callback (Callback! cb) {
-                       if (add_symbol (cb.name, cb) == null) {
-                               return;
-                       }
-                       
-                       current_symbol = cb.symbol;
+               current_symbol = iface.symbol;
+       }
+       
+       public override void visit_end_interface (Interface! iface) {
+               if (iface.error) {
+                       /* skip interfaces with errors */
+                       return;
                }
                
-               public override void visit_end_callback (Callback! cb) {
-                       if (cb.error) {
-                               /* skip enums with errors */
-                               return;
-                       }
-                       
-                       current_symbol = current_symbol.parent_symbol;
-               }
-
-               public override void visit_constant (Constant! c) {
-                       add_symbol (c.name, c);
+               current_symbol = current_symbol.parent_symbol;
+       }
+       
+       public override void visit_begin_enum (Enum! en) {
+               if (add_symbol (en.name, en) == null) {
+                       return;
                }
                
-               public override void visit_field (Field! f) {
-                       add_symbol (f.name, f);
+               current_symbol = en.symbol;
+       }
+       
+       public override void visit_end_enum (Enum! en) {
+               if (en.error) {
+                       /* skip enums with errors */
+                       return;
                }
                
-               public override void visit_begin_method (Method! m) {
-                       if (add_symbol (m.name, m) == null) {
-                               return;
-                       }
-                       
-                       if (m.instance) {
-                               if (!(m.symbol.parent_symbol.node is DataType)) {
-                                       Report.error (m.source_reference, "instance methods not allowed outside of data types");
-                               
-                                       m.error = true;
-                                       return;
-                               }
-                       
-                               m.this_parameter = new FormalParameter (name = "this", type_reference = new TypeReference ());
-                               m.this_parameter.type_reference.type = (DataType) m.symbol.parent_symbol.node;
-                               m.this_parameter.symbol = new Symbol (node = m.this_parameter);
-                               current_symbol.add (m.this_parameter.name, m.this_parameter.symbol);
-                       }
-                       
-                       current_symbol = m.symbol;
+               current_symbol = current_symbol.parent_symbol;
+       }
+
+       public override void visit_enum_value (EnumValue! ev) {
+               ev.symbol = new Symbol (node = ev);
+               current_symbol.add (ev.name, ev.symbol);
+       }
+       
+       public override void visit_begin_callback (Callback! cb) {
+               if (add_symbol (cb.name, cb) == null) {
+                       return;
                }
                
-               public override void visit_end_method (Method! m) {
-                       if (m.error) {
-                               /* skip methods with errors */
-                               return;
-                       }
-                       
-                       current_symbol = current_symbol.parent_symbol;
+               current_symbol = cb.symbol;
+       }
+       
+       public override void visit_end_callback (Callback! cb) {
+               if (cb.error) {
+                       /* skip enums with errors */
+                       return;
                }
+               
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_formal_parameter (FormalParameter! p) {
-                       if (!p.ellipsis) {
-                               add_symbol (p.name, p);
-                       }
+       public override void visit_constant (Constant! c) {
+               add_symbol (c.name, c);
+       }
+       
+       public override void visit_field (Field! f) {
+               add_symbol (f.name, f);
+       }
+       
+       public override void visit_begin_method (Method! m) {
+               if (add_symbol (m.name, m) == null) {
+                       return;
                }
                
-               public override void visit_begin_property (Property! prop) {
-                       if (add_symbol (prop.name, prop) == null) {
+               if (m.instance) {
+                       if (!(m.symbol.parent_symbol.node is DataType)) {
+                               Report.error (m.source_reference, "instance methods not allowed outside of data types");
+                       
+                               m.error = true;
                                return;
                        }
-                       
-                       current_symbol = prop.symbol;
-                       
-                       prop.this_parameter = new FormalParameter (name = "this", type_reference = new TypeReference ());
-                       prop.this_parameter.type_reference.type = (DataType) prop.symbol.parent_symbol.node;
-                       prop.this_parameter.symbol = new Symbol (node = prop.this_parameter);
-                       current_symbol.add (prop.this_parameter.name, prop.this_parameter.symbol);
+               
+                       m.this_parameter = new FormalParameter (name = "this", type_reference = new TypeReference ());
+                       m.this_parameter.type_reference.type = (DataType) m.symbol.parent_symbol.node;
+                       m.this_parameter.symbol = new Symbol (node = m.this_parameter);
+                       current_symbol.add (m.this_parameter.name, m.this_parameter.symbol);
                }
                
-               public override void visit_end_property (Property! prop) {
-                       if (prop.error) {
-                               /* skip properties with errors */
-                               return;
-                       }
-                       
-                       current_symbol = current_symbol.parent_symbol;
+               current_symbol = m.symbol;
+       }
+       
+       public override void visit_end_method (Method! m) {
+               if (m.error) {
+                       /* skip methods with errors */
+                       return;
                }
                
-               public override void visit_begin_property_accessor (PropertyAccessor! acc) {
-                       acc.symbol = new Symbol (node = acc);
-                       acc.symbol.parent_symbol = current_symbol;
-                       current_symbol = acc.symbol;
-
-                       if (acc.writable || acc.construct_) {
-                               acc.value_parameter = new FormalParameter (name = "value", type_reference = ((Property) current_symbol.parent_symbol.node).type_reference);
-                               acc.value_parameter.symbol = new Symbol (node = acc.value_parameter);
-                               
-                               current_symbol.add (acc.value_parameter.name, acc.value_parameter.symbol);
-                       }
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-                       if (acc.body == null) {
-                               /* no accessor body specified, insert default body */
-                               
-                               var prop = (Property) acc.symbol.parent_symbol.node;
-                               
-                               var block = new Block ();
-                               if (acc.readable) {
-                                       block.add_statement (new ReturnStatement (return_expression = new MemberAccess (member_name = "_%s".printf (prop.name))));
-                               } else {
-                                       block.add_statement (new ExpressionStatement (expression = new Assignment (left = new MemberAccess (member_name = "_%s".printf (prop.name)), right = new MemberAccess (member_name = "value"))));
-                               }
-                               acc.body = block;
-                       }
+       public override void visit_formal_parameter (FormalParameter! p) {
+               if (!p.ellipsis) {
+                       add_symbol (p.name, p);
+               }
+       }
+       
+       public override void visit_begin_property (Property! prop) {
+               if (add_symbol (prop.name, prop) == null) {
+                       return;
                }
                
-               public override void visit_end_property_accessor (PropertyAccessor! acc) {
-                       current_symbol = current_symbol.parent_symbol;
+               current_symbol = prop.symbol;
+               
+               prop.this_parameter = new FormalParameter (name = "this", type_reference = new TypeReference ());
+               prop.this_parameter.type_reference.type = (DataType) prop.symbol.parent_symbol.node;
+               prop.this_parameter.symbol = new Symbol (node = prop.this_parameter);
+               current_symbol.add (prop.this_parameter.name, prop.this_parameter.symbol);
+       }
+       
+       public override void visit_end_property (Property! prop) {
+               if (prop.error) {
+                       /* skip properties with errors */
+                       return;
                }
+               
+               current_symbol = current_symbol.parent_symbol;
+       }
+       
+       public override void visit_begin_property_accessor (PropertyAccessor! acc) {
+               acc.symbol = new Symbol (node = acc);
+               acc.symbol.parent_symbol = current_symbol;
+               current_symbol = acc.symbol;
 
-               public override void visit_begin_signal (Signal! sig) {
-                       if (add_symbol (sig.name, sig) == null) {
-                               return;
-                       }
+               if (acc.writable || acc.construct_) {
+                       acc.value_parameter = new FormalParameter (name = "value", type_reference = ((Property) current_symbol.parent_symbol.node).type_reference);
+                       acc.value_parameter.symbol = new Symbol (node = acc.value_parameter);
                        
-                       current_symbol = sig.symbol;
+                       current_symbol.add (acc.value_parameter.name, acc.value_parameter.symbol);
                }
 
-               public override void visit_end_signal (Signal! sig) {
-                       if (sig.error) {
-                               /* skip signals with errors */
-                               return;
-                       }
+               if (acc.body == null) {
+                       /* no accessor body specified, insert default body */
+                       
+                       var prop = (Property) acc.symbol.parent_symbol.node;
                        
-                       current_symbol = current_symbol.parent_symbol;
+                       var block = new Block ();
+                       if (acc.readable) {
+                               block.add_statement (new ReturnStatement (return_expression = new MemberAccess (member_name = "_%s".printf (prop.name))));
+                       } else {
+                               block.add_statement (new ExpressionStatement (expression = new Assignment (left = new MemberAccess (member_name = "_%s".printf (prop.name)), right = new MemberAccess (member_name = "value"))));
+                       }
+                       acc.body = block;
                }
+       }
+       
+       public override void visit_end_property_accessor (PropertyAccessor! acc) {
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_begin_constructor (Constructor! c) {
-                       c.symbol = new Symbol (node = c);
-                       c.symbol.parent_symbol = current_symbol;
-                       current_symbol = c.symbol;
+       public override void visit_begin_signal (Signal! sig) {
+               if (add_symbol (sig.name, sig) == null) {
+                       return;
                }
+               
+               current_symbol = sig.symbol;
+       }
 
-               public override void visit_end_constructor (Constructor! c) {
-                       current_symbol = current_symbol.parent_symbol;
+       public override void visit_end_signal (Signal! sig) {
+               if (sig.error) {
+                       /* skip signals with errors */
+                       return;
                }
+               
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_begin_destructor (Destructor! d) {
-                       d.symbol = new Symbol (node = d);
-                       d.symbol.parent_symbol = current_symbol;
-                       current_symbol = d.symbol;
-               }
+       public override void visit_begin_constructor (Constructor! c) {
+               c.symbol = new Symbol (node = c);
+               c.symbol.parent_symbol = current_symbol;
+               current_symbol = c.symbol;
+       }
 
-               public override void visit_end_destructor (Destructor! d) {
-                       current_symbol = current_symbol.parent_symbol;
-               }
+       public override void visit_end_constructor (Constructor! c) {
+               current_symbol = current_symbol.parent_symbol;
+       }
 
-               public override void visit_begin_block (Block! b) {
-                       b.symbol = new Symbol (node = b);
-                       b.symbol.parent_symbol = current_symbol;
-                       current_symbol = b.symbol;
-               }
+       public override void visit_begin_destructor (Destructor! d) {
+               d.symbol = new Symbol (node = d);
+               d.symbol.parent_symbol = current_symbol;
+               current_symbol = d.symbol;
+       }
 
-               public override void visit_end_block (Block! b) {
-                       current_symbol = current_symbol.parent_symbol;
-               }
-               
-               public override void visit_type_parameter (TypeParameter! p) {
-                       add_symbol (p.name, p);
-               }
+       public override void visit_end_destructor (Destructor! d) {
+               current_symbol = current_symbol.parent_symbol;
+       }
+
+       public override void visit_begin_block (Block! b) {
+               b.symbol = new Symbol (node = b);
+               b.symbol.parent_symbol = current_symbol;
+               current_symbol = b.symbol;
+       }
+
+       public override void visit_end_block (Block! b) {
+               current_symbol = current_symbol.parent_symbol;
+       }
+       
+       public override void visit_type_parameter (TypeParameter! p) {
+               add_symbol (p.name, p);
        }
 }
index 737fc07..5107638 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class SymbolResolver : CodeVisitor {
-               Symbol root_symbol;
-               Symbol current_scope;
-               List<weak NamespaceReference> current_using_directives;
+/**
+ * Code visitor resolving symbol names.
+ */
+public class Vala.SymbolResolver : CodeVisitor {
+       Symbol root_symbol;
+       Symbol current_scope;
+       List<weak NamespaceReference> current_using_directives;
+       
+       Class object_class;
+       
+       /**
+        * Resolve symbol names in the specified code context.
+        *
+        * @param context a code context
+        */
+       public void resolve (CodeContext! context) {
+               root_symbol = context.get_root ();
+               current_scope = root_symbol;
                
-               Class object_class;
+               object_class = (Class) root_symbol.lookup ("GLib").lookup ("Object").node;
                
-               public void resolve (CodeContext context) {
-                       root_symbol = context.get_root ();
-                       current_scope = root_symbol;
-                       
-                       object_class = (Class) root_symbol.lookup ("GLib").lookup ("Object").node;
-                       
-                       context.accept (this);
-               }
-               
-               public override void visit_begin_source_file (SourceFile file) {
-                       current_using_directives = file.get_using_directives ();
-               }
+               context.accept (this);
+       }
+       
+       public override void visit_begin_source_file (SourceFile! file) {
+               current_using_directives = file.get_using_directives ();
+       }
 
-               public override void visit_end_source_file (SourceFile file) {
-                       current_using_directives = null;
-               }
-               
-               public override void visit_begin_namespace (Namespace ns) {
-                       current_scope = ns.symbol;
-               }
+       public override void visit_end_source_file (SourceFile! file) {
+               current_using_directives = null;
+       }
+       
+       public override void visit_begin_namespace (Namespace! ns) {
+               current_scope = ns.symbol;
+       }
 
-               public override void visit_end_namespace (Namespace ns) {
-                       current_scope = current_scope.parent_symbol;
-               }
+       public override void visit_end_namespace (Namespace! ns) {
+               current_scope = current_scope.parent_symbol;
+       }
 
-               public override void visit_begin_class (Class cl) {
-                       current_scope = cl.symbol;
-               }
+       public override void visit_begin_class (Class! cl) {
+               current_scope = cl.symbol;
+       }
 
-               public override void visit_end_class (Class cl) {
-                       foreach (TypeReference type in cl.get_base_types ()) {
-                               if (type.type is Class) {
-                                       if (cl.base_class != null) {
-                                               Report.error (type.source_reference, "%s: Classes cannot have multiple base classes (`%s' and `%s')".printf (cl.symbol.get_full_name (), cl.base_class.symbol.get_full_name (), type.type.symbol.get_full_name ()));
-                                               return;
-                                       }
-                                       cl.base_class = (Class) type.type;
+       public override void visit_end_class (Class! cl) {
+               foreach (TypeReference type in cl.get_base_types ()) {
+                       if (type.type is Class) {
+                               if (cl.base_class != null) {
+                                       Report.error (type.source_reference, "%s: Classes cannot have multiple base classes (`%s' and `%s')".printf (cl.symbol.get_full_name (), cl.base_class.symbol.get_full_name (), type.type.symbol.get_full_name ()));
+                                       return;
                                }
+                               cl.base_class = (Class) type.type;
                        }
-                       if (cl.base_class == null && cl != object_class) {
-                               cl.base_class = object_class;
-                       }
-               
-                       current_scope = current_scope.parent_symbol;
                }
-
-               public override void visit_begin_struct (Struct st) {
-                       current_scope = st.symbol;
+               if (cl.base_class == null && cl != object_class) {
+                       cl.base_class = object_class;
                }
+       
+               current_scope = current_scope.parent_symbol;
+       }
 
-               public override void visit_end_struct (Struct st) {
-                       current_scope = current_scope.parent_symbol;
-               }
+       public override void visit_begin_struct (Struct! st) {
+               current_scope = st.symbol;
+       }
 
-               public override void visit_namespace_reference (NamespaceReference ns) {
-                       ns.namespace_symbol = current_scope.lookup (ns.name);
-                       if (ns.namespace_symbol == null) {
-                               Report.error (ns.source_reference, "The namespace name `%s' could not be found".printf (ns.name));
-                               return;
-                       }
+       public override void visit_end_struct (Struct! st) {
+               current_scope = current_scope.parent_symbol;
+       }
+
+       public override void visit_namespace_reference (NamespaceReference! ns) {
+               ns.namespace_symbol = current_scope.lookup (ns.name);
+               if (ns.namespace_symbol == null) {
+                       Report.error (ns.source_reference, "The namespace name `%s' could not be found".printf (ns.name));
+                       return;
                }
+       }
 
-               public override void visit_type_reference (TypeReference type) {
-                       if (type.type_name == "void") {
-                               return;
+       public override void visit_type_reference (TypeReference! type) {
+               if (type.type_name == "void") {
+                       return;
+               }
+               
+               if (type.namespace_name == null) {
+                       Symbol sym = null;
+                       Symbol scope = current_scope;
+                       while (sym == null && scope != null) {
+                               sym = scope.lookup (type.type_name);
+                               scope = scope.parent_symbol;
                        }
-                       
-                       if (type.namespace_name == null) {
-                               Symbol sym = null;
-                               Symbol scope = current_scope;
-                               while (sym == null && scope != null) {
-                                       sym = scope.lookup (type.type_name);
-                                       scope = scope.parent_symbol;
-                               }
-                               if (sym == null) {
-                                       foreach (NamespaceReference ns in current_using_directives) {
-                                               var local_sym = ns.namespace_symbol.lookup (type.type_name);
-                                               if (local_sym != null) {
-                                                       if (sym != null) {
-                                                               Report.error (type.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (type.type_name, sym.get_full_name (), local_sym.get_full_name ()));
-                                                               return;
-                                                       }
-                                                       sym = local_sym;
+                       if (sym == null) {
+                               foreach (NamespaceReference ns in current_using_directives) {
+                                       var local_sym = ns.namespace_symbol.lookup (type.type_name);
+                                       if (local_sym != null) {
+                                               if (sym != null) {
+                                                       Report.error (type.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (type.type_name, sym.get_full_name (), local_sym.get_full_name ()));
+                                                       return;
                                                }
+                                               sym = local_sym;
                                        }
                                }
-                               if (sym == null) {
-                                       Report.error (type.source_reference, "The type name `%s' could not be found".printf (type.type_name));
-                                       return;
-                               }
-                               if (sym.node is TypeParameter) {
-                                       type.type_parameter = (TypeParameter) sym.node;
-                               } else {
-                                       type.type = (DataType) sym.node;
-                               }
+                       }
+                       if (sym == null) {
+                               Report.error (type.source_reference, "The type name `%s' could not be found".printf (type.type_name));
+                               return;
+                       }
+                       if (sym.node is TypeParameter) {
+                               type.type_parameter = (TypeParameter) sym.node;
                        } else {
-                               var ns_symbol = root_symbol.lookup (type.namespace_name);
-                               if (ns_symbol == null) {
-                                       Report.error (type.source_reference, "The namespace name `%s' could not be found".printf (type.namespace_name));
-                                       return;
-                               }
-                               
-                               var sym = ns_symbol.lookup (type.type_name);
-                               if (sym == null) {
-                                       Report.error (type.source_reference, "The type name `%s' does not exist in the namespace `%s'".printf (type.type_name, type.namespace_name));
-                                       return;
-                               }
                                type.type = (DataType) sym.node;
                        }
+               } else {
+                       var ns_symbol = root_symbol.lookup (type.namespace_name);
+                       if (ns_symbol == null) {
+                               Report.error (type.source_reference, "The namespace name `%s' could not be found".printf (type.namespace_name));
+                               return;
+                       }
                        
-                       if (type.type != null && !type.type.is_reference_type ()) {
-                               /* reset is_lvalue_ref for contexts where types
-                                * are ref by default (field declarations)
-                                */
-                               type.is_lvalue_ref = false;
+                       var sym = ns_symbol.lookup (type.type_name);
+                       if (sym == null) {
+                               Report.error (type.source_reference, "The type name `%s' does not exist in the namespace `%s'".printf (type.type_name, type.namespace_name));
+                               return;
                        }
+                       type.type = (DataType) sym.node;
+               }
+               
+               if (type.type != null && !type.type.is_reference_type ()) {
+                       /* reset is_lvalue_ref for contexts where types
+                        * are ref by default (field declarations)
+                        */
+                       type.is_lvalue_ref = false;
                }
        }
 }