]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
support abstract methods and static fields support parameter symbol
authorJürg Billeter <j@bitron.ch>
Mon, 22 May 2006 20:04:08 +0000 (20:04 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Mon, 22 May 2006 20:04:08 +0000 (20:04 +0000)
2006-05-22  Jürg Billeter  <j@bitron.ch>

* vala/parser.y: support abstract methods and static fields
* vala/valasourcefile.vala: support parameter symbol dependencies
* vala/valasymbolbuilder.vala: insert default body for get accessors
* vala/valasemanticanalyzer.vala: add property type dependency
* vala/valacodegenerator.vala: add constants, private static fields,
  main function, property accessors, this, casting for member access
* vala/valablock.vala: add add_statement method
* vala/valafield.vala: add instance field
* vala/valamethod.vala: add is_abstract field
* valac/generator.c: mark generated properties as writable

svn path=/trunk/; revision=33

vala/ChangeLog
vala/vala/parser.y
vala/vala/valablock.vala
vala/vala/valacodegenerator.vala
vala/vala/valafield.vala
vala/vala/valamethod.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valasourcefile.vala
vala/vala/valasymbolbuilder.vala
vala/valac/generator.c

index 17234dcfb2fb2a1efcafa140cb5191377925daa9..8cce560e29ca5074f1a5a9aec33bc50410d4a91c 100644 (file)
@@ -1,3 +1,16 @@
+2006-05-22  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y: support abstract methods and static fields
+       * vala/valasourcefile.vala: support parameter symbol dependencies
+       * vala/valasymbolbuilder.vala: insert default body for get accessors
+       * vala/valasemanticanalyzer.vala: add property type dependency
+       * vala/valacodegenerator.vala: add constants, private static fields,
+         main function, property accessors, this, casting for member access
+       * vala/valablock.vala: add add_statement method
+       * vala/valafield.vala: add instance field
+       * vala/valamethod.vala: add is_abstract field
+       * valac/generator.c: mark generated properties as writable
+
 2006-05-22  Jürg Billeter  <j@bitron.ch>
 
        * vala/valacodegenerator.c: add class instance private struct, type
index 33ffbd07df2165921ac2a447730e6ca38e1ca963..bdc3c2d469e82ce416b40be2eb059cd9aa0d3d1c 100644 (file)
@@ -1099,6 +1099,9 @@ field_declaration
                if ($3 != 0) {
                        $$->access = $3;
                }
+               if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
+                       $$->instance = FALSE;
+               }
          }
        ;
 
@@ -1174,6 +1177,9 @@ method_header
                if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
                        $$->instance = FALSE;
                }
+               if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) {
+                       $$->is_abstract = TRUE;
+               }
                VALA_CODE_NODE($$)->attributes = $2;
                
                for (l = $9; l != NULL; l = l->next) {
index 3866688cb60ed8a52621069887456f5fe17e768c..f0ed1ea1f9e00f1dddf2758a2243d5de6b057e0e 100644 (file)
@@ -30,6 +30,10 @@ namespace Vala {
                        return (new Block (statement_list = statement_list, source_reference = source));
                }
                
+               public void add_statement (Statement stmt) {
+                       _statement_list.append (stmt);
+               }
+               
                public override void accept (CodeVisitor visitor) {
                        visitor.visit_begin_block (this);
 
index 9bf93bf661f39c8845b2f884112deba395d2e955..4cd3ac35b99a0eab4b480004a98ef8ffb4677fc2 100644 (file)
@@ -24,6 +24,8 @@ using GLib;
 
 namespace Vala {
        public class CodeGenerator : CodeVisitor {
+               Symbol current_symbol;
+
                CCodeFragment header_begin;
                CCodeFragment header_type_declaration;
                CCodeFragment header_type_definition;
@@ -65,9 +67,11 @@ namespace Vala {
                        source_type_member_declaration = new CCodeFragment ();
                        source_type_member_definition = new CCodeFragment ();
                        
+                       header_begin.append (new CCodeIncludeDirective (filename = "glib.h"));
                        source_include_directives.append (new CCodeIncludeDirective (filename = source_file.get_cheader_filename ()));
                        
                        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) {
@@ -178,8 +182,10 @@ namespace Vala {
                        source_type_member_declaration = null;
                        source_type_member_definition = null;
                }
-               
+
                public override void visit_begin_class (Class cl) {
+                       current_symbol = cl.symbol;
+
                        instance_struct = new CCodeStruct (name = "_%s".printf (cl.get_cname ()));
                        class_struct = new CCodeStruct (name = "_%sClass".printf (cl.get_cname ()));
                        instance_priv_struct = new CCodeStruct (name = "_%sPrivate".printf (cl.get_cname ()));
@@ -263,6 +269,9 @@ namespace Vala {
                        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;
+                       
                        source_type_member_definition.append (class_init);
                }
                
@@ -271,6 +280,9 @@ namespace Vala {
                        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;
+                       
                        source_type_member_definition.append (instance_init);
                }
                
@@ -295,16 +307,40 @@ namespace Vala {
                public override void visit_enum_value (EnumValue ev) {
                        cenum.add_value (ev.get_cname (), null);
                }
+
+               public override void visit_constant (Constant c) {
+                       if (c.symbol.parent_symbol.node is Struct) {
+                               var t = (Struct) c.symbol.parent_symbol.node;
+                               var cdecl = new CCodeDeclarationStatement (type_name = "const %s".printf (c.type_reference.get_cname ()));
+                               cdecl.add_declarator (new CCodeVariableDeclarator (name = "%s_%s".printf (t.get_lower_case_cname (null), c.name)));
+                               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.name);
                        } else if (f.access == MemberAccessibility.PRIVATE) {
-                               instance_priv_struct.add_field (f.type_reference.get_cname (), f.name);
+                               if (f.instance) {
+                                       instance_priv_struct.add_field (f.type_reference.get_cname (), f.name);
+                               } else {
+                                       if (f.symbol.parent_symbol.node is Struct) {
+                                               var t = (Struct) f.symbol.parent_symbol.node;
+                                               var cdecl = new CCodeDeclarationStatement (type_name = f.type_reference.get_cname ());
+                                               cdecl.add_declarator (new CCodeVariableDeclarator (name = "%s_%s".printf (t.get_lower_case_cname (null), f.name)));
+                                               cdecl.modifiers = CCodeModifiers.STATIC;
+                                               source_type_member_declaration.append (cdecl);
+                                       }
+                               }
                        }
                }
                
                public override void visit_end_method (Method m) {
+                       if (m.name.collate ("init") == 0) {
+                               return;
+                       }
+               
                        function = new CCodeFunction (name = m.get_cname (), return_type = m.return_type.get_cname ());
                        
                        if (m.instance) {
@@ -328,18 +364,69 @@ namespace Vala {
 
                        if (m.body != null) {
                                function.block = m.body.ccodenode;
+                       } else if (m.is_abstract) {
+                               function.block = new CCodeBlock ();
                        }
 
                        if (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.name.collate ("main") == 0) {
+                               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_formal_parameter (FormalParameter p) {
                        p.ccodenode = new CCodeFormalParameter (type_name = p.type_reference.get_cname (), name = p.name);
                }
 
+               public override void visit_begin_property (Property prop) {
+               }
+
+               public override void visit_end_property (Property prop) {
+               }
+
+               public override void visit_begin_property_accessor (PropertyAccessor acc) {
+               }
+
+               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 = acc.body.ccodenode;
+                       }
+                       
+                       source_type_member_definition.append (function);
+               }
+
                public override void visit_end_block (Block b) {
                        var cblock = new CCodeBlock ();
                        
@@ -452,19 +539,51 @@ namespace Vala {
                }
                
                public override void visit_simple_name (SimpleName expr) {
-                       if (expr.symbol_reference.node is Method) {
+                       if (expr.name.collate ("this") == 0) {
+                               expr.ccodenode = new CCodeIdentifier (name = "self");
+                       } else if (expr.symbol_reference.node is Method) {
                                var m = (Method) expr.symbol_reference.node;
                                expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
                        } else if (expr.symbol_reference.node is Field) {
                                var f = (Field) expr.symbol_reference.node;
-                               var pub_inst = new CCodeIdentifier (name = "self");
-                               ref CCodeExpression inst;
-                               if (f.access == MemberAccessibility.PRIVATE) {
-                                       inst = new CCodeMemberAccess (inner = pub_inst, member_name = "priv", is_pointer = true);
+                               if (f.instance) {
+                                       var pub_inst = new CCodeIdentifier (name = "self");
+                                       ref CCodeExpression typed_inst;
+                                       if (f.symbol.parent_symbol != current_symbol) {
+                                               typed_inst = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((Type_) 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.name, is_pointer = true);
                                } else {
-                                       inst = pub_inst;
+                                       if (f.symbol.parent_symbol.node is Struct) {
+                                               var t = (Struct) f.symbol.parent_symbol.node;
+                                               expr.ccodenode = new CCodeIdentifier (name = "%s_%s".printf (t.get_lower_case_cname (null), expr.name));
+                                       } else {
+                                               expr.ccodenode = new CCodeIdentifier (name = expr.name);
+                                       }
                                }
-                               expr.ccodenode = new CCodeMemberAccess (inner = inst, member_name = f.name, is_pointer = true);
+                       } else if (expr.symbol_reference.node is Constant) {
+                               var c = (Constant) expr.symbol_reference.node;
+                               if (c.symbol.parent_symbol.node is Struct) {
+                                       var t = (Struct) c.symbol.parent_symbol.node;
+                                       expr.ccodenode = new CCodeIdentifier (name = "%s_%s".printf (t.get_lower_case_cname (null), expr.name));
+                               } else {
+                                       expr.ccodenode = new CCodeIdentifier (name = expr.name);
+                               }
+                       } 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)));
+                               ccall.add_argument (new CCodeIdentifier (name = "self"));
+                               expr.ccodenode = ccall;
                        } else {
                                expr.ccodenode = new CCodeIdentifier (name = expr.name);
                        }
@@ -478,8 +597,34 @@ namespace Vala {
                        if (expr.symbol_reference.node is Method) {
                                var m = (Method) expr.symbol_reference.node;
                                expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
+                       } else if (expr.symbol_reference.node is Field) {
+                               var f = (Field) expr.symbol_reference.node;
+                               var pub_inst = expr.inner.ccodenode;
+                               ref CCodeExpression typed_inst;
+                               if (f.symbol.parent_symbol.node != expr.inner.static_type.type) {
+                                       typed_inst = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((Type_) 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.name, is_pointer = true);
+                       } 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)));
+                               ccall.add_argument (expr.inner.ccodenode);
+                               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 {
-                               expr.ccodenode = new CCodeIdentifier (name = expr.member_name);
+                               expr.ccodenode = new CCodeMemberAccess (inner = (CCodeExpression) expr.inner.ccodenode, member_name = expr.member_name, is_pointer = true);
                        }
                }
 
@@ -547,7 +692,23 @@ namespace Vala {
                }
 
                public override void visit_assignment (Assignment a) {
-                       a.ccodenode = new CCodeAssignment (left = (CCodeExpression) a.left.ccodenode, right = (CCodeExpression) a.right.ccodenode);
+                       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 ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name)));
+                               if (a.left is MemberAccess) {
+                                       var expr = (MemberAccess) a.left;
+                                       ccall.add_argument (expr.inner.ccodenode);
+                               } else if (a.left is SimpleName) {
+                                       ccall.add_argument (new CCodeIdentifier (name = "self"));
+                               } else {
+                                       stderr.printf ("error: unexpected lvalue in assignment\n");
+                               }
+                               ccall.add_argument ((CCodeExpression) a.right.ccodenode);
+                               a.ccodenode = ccall;
+                       } else {
+                               a.ccodenode = new CCodeAssignment (left = (CCodeExpression) a.left.ccodenode, right = (CCodeExpression) a.right.ccodenode);
+                       }
                }
        }
 }
index 9b544d5527bd74a09257fb2ffe0ccf38e6f39c6c..cd37a22471bb9ad9482ac04f4468134ccd016a3c 100644 (file)
@@ -28,6 +28,7 @@ namespace Vala {
                public TypeReference type_reference { get; construct; }
                public Expression initializer { get; construct; }
                public MemberAccessibility access;
+               public bool instance = true;
                public SourceReference source_reference { get; construct; }
                
                public static ref Field new (string name, TypeReference type, Expression init, SourceReference source) {
index 44b7e5eebc51dc35fc11288839ed53417b3f8ac8..9647fc41d149aa4b817583ee1c86f58babd95039 100644 (file)
@@ -38,6 +38,7 @@ namespace Vala {
                }
                public MemberAccessibility access;
                public bool instance = true;
+               public bool is_abstract;
                List<FormalParameter> parameters;
                public string cname;
                
index 2e7f045a7ee1efc76feecc198db8083949116c96..83935cf884984571b7dc0ee0e08e8d91274dce83 100644 (file)
@@ -108,6 +108,13 @@ namespace Vala {
                        }
                }
 
+               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);
+                       }
+               }
+
                public override void visit_named_argument (NamedArgument n) {
                }
 
index 7b19fc03d11657f8f6f3ccf17c36a8da856fc43f..c783ad6e7bf474fb68b75bb579300032d1afab0d 100644 (file)
@@ -33,6 +33,8 @@ namespace Vala {
                Namespace global_namespace;
                List<Namespace> namespaces;
                
+               TypeReference dummy_type_reference; // dummy type reference due to broken dependency handling
+               
                private void init () {
                        global_namespace = new Namespace (source_reference = new SourceReference (file = this));
                }
@@ -114,6 +116,13 @@ namespace Vala {
                                } else {
                                        return;
                                }
+                       } else if (sym.node is FormalParameter) {
+                               var fp = (FormalParameter) sym.node;
+                               t = fp.type_reference.type;
+                               if (t == null) {
+                                       /* generic type parameter */
+                                       return;
+                               }
                        } else {
                                return;
                        }
index e29bf21964ef881a2b94cdcf836b10a70954f6e3..e425a786684c2dc1ab911bf6c0ad966c4ccf2483 100644 (file)
@@ -177,6 +177,19 @@ namespace Vala {
                        if (acc.writable || acc.construct_) {
                                current_symbol.add ("value", new Symbol (node = ((Property) current_symbol.parent_symbol.node).type_reference));
                        }
+
+                       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 SimpleName (name = prop.name)));
+                               } else {
+                               }
+                               acc.body = block;
+                       }
                }
                
                public override void visit_end_property_accessor (PropertyAccessor acc) {
index dc1eace919853eb1d344b184c977e536d5955f55..000c2b6b6905b454e6714a47453c54060f912935 100644 (file)
@@ -1403,19 +1403,19 @@ vala_code_generator_process_methods2 (ValaCodeGenerator *generator, ValaClass *c
                        /* paramspec */
                        if (strcmp (prop->return_type->type_name, "string") == 0) {
                                fprintf (generator->c_file, "g_param_spec_string");
-                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)", prop->name);
+                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name);
                        } else if (prop->return_type->symbol->type == VALA_SYMBOL_TYPE_ENUM || strcmp (prop->return_type->type_name, "int") == 0) {
                                fprintf (generator->c_file, "g_param_spec_int");
-                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", G_MININT, G_MAXINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)", prop->name);
+                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", G_MININT, G_MAXINT, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name);
                        } else if (strcmp (prop->return_type->type_name, "bool") == 0) {
                                fprintf (generator->c_file, "g_param_spec_boolean");
-                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", FALSE, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)", prop->name);
+                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", FALSE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name);
                        } else if (prop->return_type->symbol->type == VALA_SYMBOL_TYPE_CLASS) {
                                fprintf (generator->c_file, "g_param_spec_object");
-                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", %sTYPE_%s, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)", prop->name, prop->return_type->symbol->class->namespace->upper_case_cname, prop->return_type->symbol->class->upper_case_cname);
+                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", %sTYPE_%s, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name, prop->return_type->symbol->class->namespace->upper_case_cname, prop->return_type->symbol->class->upper_case_cname);
                        } else {
                                fprintf (generator->c_file, "g_param_spec_pointer");
-                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)", prop->name);
+                               fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name);
                        }
                        
                        fprintf (generator->c_file, ");\n");