From: Jürg Billeter Date: Mon, 30 Mar 2009 22:31:07 +0000 (+0200) Subject: Rework header file generation X-Git-Tag: 0.7.0~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d4a4a264677b42710914907f63e1624e25e560f;p=thirdparty%2Fvala.git Rework header file generation Generate single C header file for public API, do not use header files for internal API. Fixes bug 471244, bug 571037, bug 572536, and bug 575629. --- diff --git a/gobject/valaccodearraymodule.vala b/gobject/valaccodearraymodule.vala index 06ad8b9ad..d9f5c55b3 100644 --- a/gobject/valaccodearraymodule.vala +++ b/gobject/valaccodearraymodule.vala @@ -693,12 +693,20 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule { assignment.ccodenode = ccall; } - public override void generate_parameter (FormalParameter param, Map cparam_map, Map? carg_map) { + public override void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map cparam_map, Map? carg_map) { if (!(param.parameter_type is ArrayType)) { - base.generate_parameter (param, cparam_map, carg_map); + base.generate_parameter (param, decl_space, cparam_map, carg_map); return; } + string ctypename = param.parameter_type.get_cname (); + + if (param.direction != ParameterDirection.IN) { + ctypename += "*"; + } + + param.ccodenode = new CCodeFormalParameter (param.name, ctypename); + var array_type = (ArrayType) param.parameter_type; cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode); diff --git a/gobject/valaccodeassignmentmodule.vala b/gobject/valaccodeassignmentmodule.vala index 332bb4f03..eb2a1fd16 100644 --- a/gobject/valaccodeassignmentmodule.vala +++ b/gobject/valaccodeassignmentmodule.vala @@ -38,6 +38,18 @@ internal class Vala.CCodeAssignmentModule : CCodeMemberAccessModule { var prop = (Property) assignment.left.symbol_reference; + if (!(prop is DynamicProperty)) { + generate_property_accessor_declaration (prop.set_accessor, source_declarations); + + if (!prop.external && prop.external_package) { + // internal VAPI properties + // only add them once per source file + if (add_generated_external_symbol (prop)) { + visit_property (prop); + } + } + } + if (prop.set_accessor.construction && current_type_symbol is Class && current_class.is_subtype_of (gobject_type) && in_creation_method) { return head.get_construct_property_assignment (prop.get_canonical_cconstant (), prop.property_type, (CCodeExpression) assignment.right.ccodenode); } else { diff --git a/gobject/valaccodebasemodule.vala b/gobject/valaccodebasemodule.vala index 9bfa75c75..f7803c910 100644 --- a/gobject/valaccodebasemodule.vala +++ b/gobject/valaccodebasemodule.vala @@ -54,13 +54,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { public CCodeFragment module_init_fragment; public CCodeStruct param_spec_struct; - public CCodeStruct instance_struct; - public CCodeStruct type_struct; - public CCodeStruct instance_priv_struct; - public CCodeStruct type_priv_struct; public CCodeStruct closure_struct; public CCodeEnum prop_enum; - public CCodeEnum cenum; public CCodeFunction function; // code nodes to be inserted before the current statement @@ -127,7 +122,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { public bool string_h_needed; public bool gvaluecollector_h_needed; public bool gio_h_needed; - public bool requires_free_checked; public bool requires_array_free; public bool requires_array_move; public bool requires_array_length; @@ -136,9 +130,12 @@ internal class Vala.CCodeBaseModule : CCodeModule { public bool dbus_glib_h_needed_in_header; public Set wrappers; + Set generated_external_symbols; public Map variable_name_map = new HashMap (str_hash, str_equal); + string? legacy_header_define; + public CCodeBaseModule (CCodeGenerator codegen, CCodeModule? next) { base (codegen, next); @@ -207,6 +204,148 @@ internal class Vala.CCodeBaseModule : CCodeModule { c_keywords.add ("cdecl"); } + public override void emit (CodeContext context) { + this.context = context; + + root_symbol = context.root; + + bool_type = new BooleanType ((Struct) root_symbol.scope.lookup ("bool")); + char_type = new IntegerType ((Struct) root_symbol.scope.lookup ("char")); + uchar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uchar")); + unichar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("unichar")); + short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short")); + ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort")); + int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int")); + uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint")); + long_type = new IntegerType ((Struct) root_symbol.scope.lookup ("long")); + ulong_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ulong")); + int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8")); + uint8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint8")); + int16_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int16")); + uint16_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint16")); + int32_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int32")); + uint32_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint32")); + int64_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int64")); + uint64_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint64")); + float_type = new FloatingType ((Struct) root_symbol.scope.lookup ("float")); + double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double")); + string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string")); + + var glib_ns = root_symbol.scope.lookup ("GLib"); + + gtype_type = (TypeSymbol) glib_ns.scope.lookup ("Type"); + gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object"); + gerror_type = new ErrorType (null, null); + glist_type = (Class) glib_ns.scope.lookup ("List"); + gslist_type = (Class) glib_ns.scope.lookup ("SList"); + gstringbuilder_type = (TypeSymbol) glib_ns.scope.lookup ("StringBuilder"); + garray_type = (TypeSymbol) glib_ns.scope.lookup ("Array"); + gbytearray_type = (TypeSymbol) glib_ns.scope.lookup ("ByteArray"); + gptrarray_type = (TypeSymbol) glib_ns.scope.lookup ("PtrArray"); + + gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark")); + gvalue_type = (Struct) glib_ns.scope.lookup ("Value"); + mutex_type = (Struct) glib_ns.scope.lookup ("StaticRecMutex"); + + type_module_type = (TypeSymbol) glib_ns.scope.lookup ("TypeModule"); + + if (context.module_init_method != null) { + module_init_fragment = new CCodeFragment (); + foreach (FormalParameter parameter in context.module_init_method.get_parameters ()) { + if (parameter.parameter_type.data_type == type_module_type) { + in_plugin = true; + module_init_param_name = parameter.name; + break; + } + } + } + + var dbus_ns = root_symbol.scope.lookup ("DBus"); + if (dbus_ns != null) { + dbus_object_type = (TypeSymbol) dbus_ns.scope.lookup ("Object"); + } + + header_declarations = new CCodeDeclarationSpace (); + + /* we're only interested in non-pkg source files */ + var source_files = context.get_source_files (); + foreach (SourceFile file in source_files) { + if (!file.external_package) { + file.accept (codegen); + } + } + + // generate C header file for public API + if (context.header_filename != null) { + var writer = new CCodeWriter (context.header_filename); + if (!writer.open ()) { + Report.error (null, "unable to open `%s' for writing".printf (writer.filename)); + return; + } + writer.write_newline (); + + var once = new CCodeOnceSection (get_define_for_filename (writer.filename)); + once.append (new CCodeNewline ()); + once.append (header_declarations.include_directives); + once.append (new CCodeNewline ()); + once.append (new CCodeIdentifier ("G_BEGIN_DECLS")); + once.append (new CCodeNewline ()); + once.append (new CCodeNewline ()); + once.append (header_declarations.type_declaration); + once.append (new CCodeNewline ()); + once.append (header_declarations.type_definition); + once.append (new CCodeNewline ()); + once.append (header_declarations.type_member_declaration); + once.append (new CCodeNewline ()); + once.append (header_declarations.constant_declaration); + once.append (new CCodeNewline ()); + once.append (new CCodeIdentifier ("G_END_DECLS")); + once.append (new CCodeNewline ()); + once.append (new CCodeNewline ()); + once.write (writer); + writer.close (); + } else if (context.legacy_headers) { + foreach (SourceFile file in source_files) { + if (file.external_package) { + continue; + } + + if (legacy_header_define == null) { + // share the same define for all legacy headers + legacy_header_define = get_define_for_filename (file.get_cinclude_filename ()); + } + + var writer = new CCodeWriter (file.get_cheader_filename ()); + if (!writer.open ()) { + Report.error (null, "unable to open `%s' for writing".printf (writer.filename)); + return; + } + writer.write_newline (); + + var once = new CCodeOnceSection (legacy_header_define); + once.append (new CCodeNewline ()); + once.append (header_declarations.include_directives); + once.append (new CCodeNewline ()); + once.append (new CCodeIdentifier ("G_BEGIN_DECLS")); + once.append (new CCodeNewline ()); + once.append (new CCodeNewline ()); + once.append (header_declarations.type_declaration); + once.append (new CCodeNewline ()); + once.append (header_declarations.type_definition); + once.append (new CCodeNewline ()); + once.append (header_declarations.type_member_declaration); + once.append (new CCodeNewline ()); + once.append (header_declarations.constant_declaration); + once.append (new CCodeNewline ()); + once.append (new CCodeIdentifier ("G_END_DECLS")); + once.append (new CCodeNewline ()); + once.append (new CCodeNewline ()); + once.write (writer); + writer.close (); + } + } + } + public override CCodeIdentifier get_value_setter_function (DataType type_reference) { if (type_reference.data_type != null) { return new CCodeIdentifier (type_reference.data_type.get_set_value_function ()); @@ -261,7 +400,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { } public override void visit_source_file (SourceFile source_file) { - header_declarations = new CCodeDeclarationSpace (); source_declarations = new CCodeDeclarationSpace (); source_type_member_definition = new CCodeFragment (); source_signal_marshaller_definition = new CCodeFragment (); @@ -277,80 +415,16 @@ internal class Vala.CCodeBaseModule : CCodeModule { gio_h_needed = false; dbus_glib_h_needed = false; dbus_glib_h_needed_in_header = false; - requires_free_checked = false; requires_array_free = false; requires_array_move = false; requires_array_length = false; requires_strcmp0 = false; wrappers = new HashSet (str_hash, str_equal); + generated_external_symbols = new HashSet (); - header_declarations.add_include ("glib.h"); - header_declarations.add_include ("glib-object.h"); - - if (context.legacy_headers) { - if (context.basedir != null || context.library != null) { - source_declarations.add_include (source_file.get_cinclude_filename ()); - } else { - source_declarations.add_include (source_file.get_cinclude_filename (), true); - } - } - - Gee.List used_includes = new ArrayList (str_equal); - used_includes.add ("glib.h"); - used_includes.add ("glib-object.h"); - - if (context.legacy_headers) { - used_includes.add (source_file.get_cinclude_filename ()); - - foreach (string filename in source_file.get_header_external_includes ()) { - if (!used_includes.contains (filename)) { - header_declarations.add_include (filename); - used_includes.add (filename); - } - } - foreach (string filename in source_file.get_header_internal_includes ()) { - if (!used_includes.contains (filename)) { - header_declarations.add_include (filename, (context.library == null)); - used_includes.add (filename); - } - } - foreach (string filename in source_file.get_source_external_includes ()) { - if (!used_includes.contains (filename)) { - source_declarations.add_include (filename); - used_includes.add (filename); - } - } - foreach (string filename in source_file.get_source_internal_includes ()) { - if (!used_includes.contains (filename)) { - source_declarations.add_include (filename, (context.library == null)); - used_includes.add (filename); - } - } - if (source_file.is_cycle_head) { - foreach (SourceFile cycle_file in source_file.cycle.files) { - foreach (CodeNode node in cycle_file.get_nodes ()) { - if (node is Struct) { - var st = (Struct) node; - header_declarations.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ()))); - } else if (node is Class) { - var cl = (Class) node; - header_declarations.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ()))); - header_declarations.add_type_declaration (new CCodeTypeDefinition ("struct _%sClass".printf (cl.get_cname ()), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ())))); - } else if (node is Interface) { - var iface = (Interface) node; - header_declarations.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ()))); - header_declarations.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (iface.get_type_cname ()), new CCodeVariableDeclarator (iface.get_type_cname ()))); - } - } - } - } - } - foreach (Symbol symbol in source_file.get_source_symbol_dependencies ()) { - if (!symbol.external && symbol.external_package) { - symbol.accept (codegen); - } - } + source_declarations.add_include ("glib.h"); + source_declarations.add_include ("glib-object.h"); source_file.accept_children (codegen); @@ -358,12 +432,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { return; } - var header_define = get_define_for_filename (source_file.get_cinclude_filename ()); - - /* generate hardcoded "well-known" macros */ - if (requires_free_checked) { - source_declarations.add_begin (new CCodeMacroReplacement ("VALA_FREE_CHECKED(o,f)", "((o) == NULL ? NULL : ((o) = (f (o), NULL)))")); - } if (requires_array_free) { append_vala_array_free (); } @@ -385,15 +453,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { source_declarations.add_include ("gobject/gvaluecollector.h"); } - if (gio_h_needed) { - header_declarations.add_include ("gio/gio.h"); - } - - if (dbus_glib_h_needed_in_header) { - header_declarations.add_include ("dbus/dbus.h"); - header_declarations.add_include ("dbus/dbus-glib.h"); - header_declarations.add_include ("dbus/dbus-glib-lowlevel.h"); - } else if (dbus_glib_h_needed) { + if (dbus_glib_h_needed) { source_declarations.add_include ("dbus/dbus.h"); source_declarations.add_include ("dbus/dbus-glib.h"); source_declarations.add_include ("dbus/dbus-glib-lowlevel.h"); @@ -484,38 +544,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { if (source_file.comment != null) { comment = new CCodeComment (source_file.comment); } - - if (context.legacy_headers) { - var writer = new CCodeWriter (source_file.get_cheader_filename ()); - if (!writer.open ()) { - Report.error (null, "unable to open `%s' for writing".printf (writer.filename)); - return; - } - if (comment != null) { - comment.write (writer); - } - writer.write_newline (); - var once = new CCodeOnceSection (header_define); - once.append (new CCodeNewline ()); - once.append (header_declarations.include_directives); - once.append (new CCodeNewline ()); - once.append (new CCodeIdentifier ("G_BEGIN_DECLS")); - once.append (new CCodeNewline ()); - once.append (new CCodeNewline ()); - once.append (header_declarations.type_declaration); - once.append (new CCodeNewline ()); - once.append (header_declarations.type_definition); - once.append (new CCodeNewline ()); - once.append (header_declarations.type_member_declaration); - once.append (new CCodeNewline ()); - once.append (header_declarations.constant_declaration); - once.append (new CCodeNewline ()); - once.append (new CCodeIdentifier ("G_END_DECLS")); - once.append (new CCodeNewline ()); - once.append (new CCodeNewline ()); - once.write (writer); - writer.close (); - } var writer = new CCodeWriter (source_file.get_csource_filename ()); if (!writer.open ()) { @@ -526,7 +554,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { if (comment != null) { comment.write (writer); } - source_declarations.begin.write (writer); writer.write_newline (); source_declarations.include_directives.write (writer); writer.write_newline (); @@ -549,7 +576,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { writer.write_newline (); writer.close (); - header_declarations = null; source_declarations = null; source_type_member_definition = null; source_signal_marshaller_definition = null; @@ -576,108 +602,20 @@ internal class Vala.CCodeBaseModule : CCodeModule { return define.str; } - public override void emit (CodeContext context) { - this.context = context; - - if (context.legacy_headers) { - context.find_header_cycles (); - } - - root_symbol = context.root; - - bool_type = new BooleanType ((Struct) root_symbol.scope.lookup ("bool")); - char_type = new IntegerType ((Struct) root_symbol.scope.lookup ("char")); - uchar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uchar")); - unichar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("unichar")); - short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short")); - ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort")); - int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int")); - uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint")); - long_type = new IntegerType ((Struct) root_symbol.scope.lookup ("long")); - ulong_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ulong")); - int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8")); - uint8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint8")); - int16_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int16")); - uint16_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint16")); - int32_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int32")); - uint32_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint32")); - int64_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int64")); - uint64_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint64")); - float_type = new FloatingType ((Struct) root_symbol.scope.lookup ("float")); - double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double")); - string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string")); - - var glib_ns = root_symbol.scope.lookup ("GLib"); - - gtype_type = (TypeSymbol) glib_ns.scope.lookup ("Type"); - gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object"); - gerror_type = new ErrorType (null, null); - glist_type = (Class) glib_ns.scope.lookup ("List"); - gslist_type = (Class) glib_ns.scope.lookup ("SList"); - gstringbuilder_type = (TypeSymbol) glib_ns.scope.lookup ("StringBuilder"); - garray_type = (TypeSymbol) glib_ns.scope.lookup ("Array"); - gbytearray_type = (TypeSymbol) glib_ns.scope.lookup ("ByteArray"); - gptrarray_type = (TypeSymbol) glib_ns.scope.lookup ("PtrArray"); - - gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark")); - gvalue_type = (Struct) glib_ns.scope.lookup ("Value"); - mutex_type = (Struct) glib_ns.scope.lookup ("StaticRecMutex"); - - type_module_type = (TypeSymbol) glib_ns.scope.lookup ("TypeModule"); - - if (context.module_init_method != null) { - module_init_fragment = new CCodeFragment (); - foreach (FormalParameter parameter in context.module_init_method.get_parameters ()) { - if (parameter.parameter_type.data_type == type_module_type) { - in_plugin = true; - module_init_param_name = parameter.name; - break; - } - } + public void generate_enum_declaration (Enum en, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (en, en.get_cname ())) { + return; } - var dbus_ns = root_symbol.scope.lookup ("DBus"); - if (dbus_ns != null) { - dbus_object_type = (TypeSymbol) dbus_ns.scope.lookup ("Object"); - } - - /* we're only interested in non-pkg source files */ - var source_files = context.get_source_files (); - foreach (SourceFile file in source_files) { - if (!file.external_package) { - file.accept (codegen); - } - } + var cenum = new CCodeEnum (en.get_cname ()); - // generate C header file for public API - if (context.header_filename != null) { - var writer = new CCodeWriter (context.header_filename); - if (!writer.open ()) { - Report.error (null, "unable to open `%s' for writing".printf (writer.filename)); - return; + foreach (EnumValue ev in en.get_values ()) { + if (ev.value == null) { + cenum.add_value (new CCodeEnumValue (ev.get_cname ())); + } else { + ev.value.accept (codegen); + cenum.add_value (new CCodeEnumValue (ev.get_cname (), (CCodeExpression) ev.value.ccodenode)); } - writer.write_newline (); - var once = new CCodeOnceSection (get_define_for_filename (writer.filename)); - once.append (new CCodeNewline ()); - once.append (new CCodeIdentifier ("G_BEGIN_DECLS")); - once.append (new CCodeNewline ()); - once.append (new CCodeNewline ()); - once.append (new CCodeIdentifier ("G_END_DECLS")); - once.append (new CCodeNewline ()); - once.append (new CCodeNewline ()); - once.write (writer); - writer.close (); - } - } - - public override void visit_enum (Enum en) { - cenum = new CCodeEnum (en.get_cname ()); - - CCodeDeclarationSpace decl_space; - if (en.access != SymbolAccessibility.PRIVATE) { - decl_space = header_declarations; - } else { - decl_space = source_declarations; } if (en.source_reference.comment != null) { @@ -687,8 +625,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { decl_space.add_type_definition (cenum); decl_space.add_type_definition (new CCodeNewline ()); - en.accept_children (codegen); - if (!en.has_type_id) { return; } @@ -698,6 +634,29 @@ internal class Vala.CCodeBaseModule : CCodeModule { var macro = "(%s_get_type ())".printf (en.get_lower_case_cname (null)); decl_space.add_type_declaration (new CCodeMacroReplacement (en.get_type_id (), macro)); + var fun_name = "%s_get_type".printf (en.get_lower_case_cname (null)); + var regfun = new CCodeFunction (fun_name, "GType"); + + if (en.access == SymbolAccessibility.PRIVATE) { + regfun.modifiers = CCodeModifiers.STATIC; + } + + decl_space.add_type_member_declaration (regfun); + } + + public override void visit_enum (Enum en) { + en.accept_children (codegen); + + generate_enum_declaration (en, source_declarations); + + if (!en.is_internal_symbol ()) { + generate_enum_declaration (en, header_declarations); + } + + if (!en.has_type_id) { + return; + } + var clist = new CCodeInitializerList (); /* or during visit time? */ CCodeInitializerList clist_ev = null; foreach (EnumValue ev in en.get_values ()) { @@ -759,10 +718,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { regblock.add_statement (new CCodeReturnStatement (new CCodeConstant (type_id_name))); - if (en.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (regfun.copy ()); - } else { - source_declarations.add_type_member_declaration (regfun.copy ()); + if (en.access == SymbolAccessibility.PRIVATE) { + regfun.modifiers = CCodeModifiers.STATIC; } regfun.block = regblock; @@ -770,44 +727,29 @@ internal class Vala.CCodeBaseModule : CCodeModule { source_type_member_definition.append (regfun); } - public override void visit_enum_value (EnumValue ev) { - if (ev.value == null) { - cenum.add_value (new CCodeEnumValue (ev.get_cname ())); - } else { - ev.value.accept (codegen); - cenum.add_value (new CCodeEnumValue (ev.get_cname (), (CCodeExpression) ev.value.ccodenode)); - } - } - public override void visit_member (Member m) { /* stuff meant for all lockable members */ - if (m is Lockable && ((Lockable)m).get_lock_used ()) { + if (m is Lockable && ((Lockable) m).get_lock_used ()) { CCodeExpression l = new CCodeIdentifier ("self"); - l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (m)); - - instance_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (m)); - - var initf = new CCodeFunctionCall ( - new CCodeIdentifier (mutex_type.default_construction_method.get_cname ())); - - initf.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l)); + l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (m)); + var initf = new CCodeFunctionCall (new CCodeIdentifier (mutex_type.default_construction_method.get_cname ())); + initf.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l)); instance_init_fragment.append (new CCodeExpressionStatement (initf)); - - requires_free_checked = true; - - - var fc = new CCodeFunctionCall (new CCodeIdentifier ("g_static_rec_mutex_free")); - - fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l)); if (instance_finalize_fragment != null) { + var fc = new CCodeFunctionCall (new CCodeIdentifier ("g_static_rec_mutex_free")); + fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l)); instance_finalize_fragment.append (new CCodeExpressionStatement (fc)); } } } - public override void visit_constant (Constant c) { + public void generate_constant_declaration (Constant c, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (c, c.get_cname ())) { + return; + } + c.accept_children (codegen); if (c.initializer is InitializerList) { @@ -819,17 +761,60 @@ internal class Vala.CCodeBaseModule : CCodeModule { cdecl.add_declarator (new CCodeVariableDeclarator ("%s%s".printf (c.get_cname (), arr), (CCodeExpression) c.initializer.ccodenode)); cdecl.modifiers = CCodeModifiers.STATIC; - if (!c.is_internal_symbol ()) { - header_declarations.add_constant_declaration (cdecl); - } else { - source_declarations.add_constant_declaration (cdecl); - } + decl_space.add_constant_declaration (cdecl); } else { var cdefine = new CCodeMacroReplacement.with_expression (c.get_cname (), (CCodeExpression) c.initializer.ccodenode); - if (!c.is_internal_symbol ()) { - header_declarations.add_type_member_declaration (cdefine); - } else { - source_declarations.add_type_member_declaration (cdefine); + decl_space.add_type_member_declaration (cdefine); + } + } + + public override void visit_constant (Constant c) { + generate_constant_declaration (c, source_declarations); + } + + void generate_field_declaration (Field f, CCodeDeclarationSpace decl_space) { + string field_ctype = f.field_type.get_cname (); + if (f.is_volatile) { + field_ctype = "volatile " + field_ctype; + } + + var cdecl = new CCodeDeclaration (field_ctype); + cdecl.add_declarator (new CCodeVariableDeclarator (f.get_cname ())); + if (f.is_private_symbol ()) { + cdecl.modifiers = CCodeModifiers.STATIC; + } else { + cdecl.modifiers = CCodeModifiers.EXTERN; + } + decl_space.add_type_member_declaration (cdecl); + + if (f.field_type is ArrayType && !f.no_array_length) { + var array_type = (ArrayType) f.field_type; + + for (int dim = 1; dim <= array_type.rank; dim++) { + var len_type = int_type.copy (); + + cdecl = new CCodeDeclaration (len_type.get_cname ()); + cdecl.add_declarator (new CCodeVariableDeclarator (head.get_array_length_cname (f.get_cname (), dim))); + if (f.is_private_symbol ()) { + cdecl.modifiers = CCodeModifiers.STATIC; + } else { + cdecl.modifiers = CCodeModifiers.EXTERN; + } + decl_space.add_type_member_declaration (cdecl); + } + } else if (f.field_type is DelegateType) { + var delegate_type = (DelegateType) f.field_type; + if (delegate_type.delegate_symbol.has_target) { + // create field to store delegate target + + cdecl = new CCodeDeclaration ("gpointer"); + cdecl.add_declarator (new CCodeVariableDeclarator (get_delegate_target_cname (f.get_cname ()))); + if (f.is_private_symbol ()) { + cdecl.modifiers = CCodeModifiers.STATIC; + } else { + cdecl.modifiers = CCodeModifiers.EXTERN; + } + decl_space.add_type_member_declaration (cdecl); } } } @@ -843,8 +828,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { bool is_gtypeinstance = (cl != null && !cl.is_compact); CCodeExpression lhs = null; - CCodeStruct st = null; - + string field_ctype = f.field_type.get_cname (); if (f.is_volatile) { field_ctype = "volatile " + field_ctype; @@ -852,34 +836,11 @@ internal class Vala.CCodeBaseModule : CCodeModule { if (f.binding == MemberBinding.INSTANCE) { if (is_gtypeinstance && f.access == SymbolAccessibility.PRIVATE) { - st = instance_priv_struct; lhs = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), f.get_cname ()); } else { - st = instance_struct; lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.get_cname ()); } - st.add_field (field_ctype, f.get_cname ()); - if (f.field_type is ArrayType && !f.no_array_length) { - // create fields to store array dimensions - var array_type = (ArrayType) f.field_type; - var len_type = int_type.copy (); - - for (int dim = 1; dim <= array_type.rank; dim++) { - st.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim)); - } - - if (array_type.rank == 1 && f.is_internal_symbol ()) { - st.add_field (len_type.get_cname (), head.get_array_size_cname (f.name)); - } - } else if (f.field_type is DelegateType) { - var delegate_type = (DelegateType) f.field_type; - if (delegate_type.delegate_symbol.has_target) { - // create field to store delegate target - st.add_field ("gpointer", get_delegate_target_cname (f.name)); - } - } - if (f.initializer != null) { var rhs = (CCodeExpression) f.initializer.ccodenode; @@ -927,24 +888,15 @@ internal class Vala.CCodeBaseModule : CCodeModule { f.error = true; return; } - - if (f.access != SymbolAccessibility.PRIVATE) { - st = type_struct; - } else { - st = type_priv_struct; - } - - st.add_field (field_ctype, f.get_cname ()); } else { - lhs = new CCodeIdentifier (f.get_cname ()); + generate_field_declaration (f, source_declarations); if (!f.is_internal_symbol ()) { - var cdecl = new CCodeDeclaration (field_ctype); - cdecl.add_declarator (new CCodeVariableDeclarator (f.get_cname ())); - cdecl.modifiers = CCodeModifiers.EXTERN; - header_declarations.add_type_member_declaration (cdecl); + generate_field_declaration (f, header_declarations); } + lhs = new CCodeIdentifier (f.get_cname ()); + var var_decl = new CCodeVariableDeclarator (f.get_cname ()); var_decl.initializer = default_value_for_type (f.field_type, true); @@ -957,7 +909,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { var var_def = new CCodeDeclaration (field_ctype); var_def.add_declarator (var_decl); - if (!f.is_internal_symbol ()) { + if (!f.is_private_symbol ()) { var_def.modifiers = CCodeModifiers.EXTERN; } else { var_def.modifiers = CCodeModifiers.STATIC; @@ -971,16 +923,9 @@ internal class Vala.CCodeBaseModule : CCodeModule { for (int dim = 1; dim <= array_type.rank; dim++) { var len_type = int_type.copy (); - if (!f.is_internal_symbol ()) { - var cdecl = new CCodeDeclaration (len_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator (head.get_array_length_cname (f.get_cname (), dim))); - cdecl.modifiers = CCodeModifiers.EXTERN; - header_declarations.add_type_member_declaration (cdecl); - } - var len_def = new CCodeDeclaration (len_type.get_cname ()); len_def.add_declarator (new CCodeVariableDeclarator (head.get_array_length_cname (f.get_cname (), dim), new CCodeConstant ("0"))); - if (!f.is_internal_symbol ()) { + if (!f.is_private_symbol ()) { len_def.modifiers = CCodeModifiers.EXTERN; } else { len_def.modifiers = CCodeModifiers.STATIC; @@ -1001,16 +946,9 @@ internal class Vala.CCodeBaseModule : CCodeModule { if (delegate_type.delegate_symbol.has_target) { // create field to store delegate target - if (!f.is_internal_symbol ()) { - var cdecl = new CCodeDeclaration ("gpointer"); - cdecl.add_declarator (new CCodeVariableDeclarator (get_delegate_target_cname (f.get_cname ()))); - cdecl.modifiers = CCodeModifiers.EXTERN; - header_declarations.add_type_member_declaration (cdecl); - } - var target_def = new CCodeDeclaration ("gpointer"); target_def.add_declarator (new CCodeVariableDeclarator (get_delegate_target_cname (f.get_cname ()), new CCodeConstant ("NULL"))); - if (!f.is_internal_symbol ()) { + if (!f.is_private_symbol ()) { target_def.modifiers = CCodeModifiers.EXTERN; } else { target_def.modifiers = CCodeModifiers.STATIC; @@ -1105,33 +1043,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { check_type (p.parameter_type); p.accept_children (codegen); - - if (!p.ellipsis) { - string ctypename = p.parameter_type.get_cname (); - string cname = p.name; - - // pass non-simple structs always by reference - if (p.parameter_type.data_type is Struct) { - var st = (Struct) p.parameter_type.data_type; - if (!st.is_simple_type () && p.direction == ParameterDirection.IN) { - if (st.use_const) { - ctypename = "const " + ctypename; - } - - if (!p.parameter_type.nullable) { - ctypename += "*"; - } - } - } - - if (p.direction != ParameterDirection.IN) { - ctypename += "*"; - } - - p.ccodenode = new CCodeFormalParameter (cname, ctypename); - } else { - p.ccodenode = new CCodeFormalParameter.with_ellipsis (); - } } public override void visit_property (Property prop) { @@ -1148,6 +1059,82 @@ internal class Vala.CCodeBaseModule : CCodeModule { variable_name_map = old_variable_name_map; } + public void generate_type_declaration (DataType type, CCodeDeclarationSpace decl_space) { + if (type is ObjectType) { + var object_type = (ObjectType) type; + if (object_type.type_symbol is Class) { + generate_class_declaration ((Class) object_type.type_symbol, decl_space); + } else if (object_type.type_symbol is Interface) { + generate_interface_declaration ((Interface) object_type.type_symbol, decl_space); + } + } else if (type is DelegateType) { + var deleg_type = (DelegateType) type; + var d = deleg_type.delegate_symbol; + generate_delegate_declaration (d, decl_space); + } else if (type.data_type is Enum) { + var en = (Enum) type.data_type; + generate_enum_declaration (en, decl_space); + } else if (type is StructValueType) { + var struct_type = (StructValueType) type; + generate_struct_declaration ((Struct) struct_type.type_symbol, decl_space); + } + + foreach (DataType type_arg in type.get_type_arguments ()) { + generate_type_declaration (type_arg, decl_space); + } + } + + public virtual void generate_class_struct_declaration (Class cl, CCodeDeclarationSpace decl_space) { + } + + public virtual void generate_struct_declaration (Struct st, CCodeDeclarationSpace decl_space) { + } + + public virtual void generate_delegate_declaration (Delegate d, CCodeDeclarationSpace decl_space) { + } + + public virtual void generate_cparameters (Method m, CCodeDeclarationSpace decl_space, Map cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) { + } + + public void generate_property_accessor_declaration (PropertyAccessor acc, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (acc.prop, acc.get_cname ())) { + return; + } + + var prop = (Property) acc.prop; + + bool returns_real_struct = prop.property_type.is_real_struct_type (); + + var t = (ObjectTypeSymbol) prop.parent_symbol; + + var this_type = new ObjectType (t); + generate_type_declaration (this_type, decl_space); + var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ()); + + CCodeFormalParameter cvalueparam; + if (returns_real_struct) { + cvalueparam = new CCodeFormalParameter ("value", acc.value_type.get_cname () + "*"); + } else { + cvalueparam = new CCodeFormalParameter ("value", acc.value_type.get_cname ()); + } + generate_type_declaration (acc.value_type, decl_space); + + if (acc.readable && !returns_real_struct) { + function = new CCodeFunction (acc.get_cname (), acc.value_type.get_cname ()); + } else { + function = new CCodeFunction (acc.get_cname (), "void"); + } + function.add_parameter (cselfparam); + if (acc.writable || acc.construction || returns_real_struct) { + function.add_parameter (cvalueparam); + } + + if (prop.is_private_symbol () || (!acc.readable && !acc.writable) || acc.access == SymbolAccessibility.PRIVATE) { + function.modifiers |= CCodeModifiers.STATIC; + } + decl_space.add_type_member_declaration (function); + } + public override void visit_property_accessor (PropertyAccessor acc) { current_property_accessor = acc; current_method_inner_error = false; @@ -1156,6 +1143,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { bool returns_real_struct = prop.property_type.is_real_struct_type (); + var old_return_type = current_return_type; if (acc.readable && !returns_real_struct) { current_return_type = prop.property_type; } else { @@ -1164,7 +1152,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { acc.accept_children (codegen); - var t = (TypeSymbol) prop.parent_symbol; + var t = (ObjectTypeSymbol) prop.parent_symbol; if (acc.construction && !t.is_subtype_of (gobject_type)) { Report.error (acc.source_reference, "construct properties require GLib.Object"); @@ -1172,12 +1160,19 @@ internal class Vala.CCodeBaseModule : CCodeModule { return; } - ReferenceType this_type; - if (t is Class) { - this_type = new ObjectType ((Class) t); - } else { - this_type = new ObjectType ((Interface) t); + // do not declare overriding properties and interface implementations + if (prop.is_abstract || prop.is_virtual + || (prop.base_property == null && prop.base_interface_property == null)) { + generate_property_accessor_declaration (acc, source_declarations); + + if (!prop.is_internal_symbol () + && (acc.access == SymbolAccessibility.PUBLIC + || acc.access == SymbolAccessibility.PROTECTED)) { + generate_property_accessor_declaration (acc, header_declarations); + } } + + var this_type = new ObjectType (t); var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ()); CCodeFormalParameter cvalueparam; if (returns_real_struct) { @@ -1187,38 +1182,21 @@ internal class Vala.CCodeBaseModule : CCodeModule { } if (prop.is_abstract || prop.is_virtual) { - CCodeFunctionDeclarator vdeclarator; - if (acc.readable) { function = new CCodeFunction (acc.get_cname (), current_return_type.get_cname ()); - - var vdecl = new CCodeDeclaration (current_return_type.get_cname ()); - vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name)); - vdecl.add_declarator (vdeclarator); - type_struct.add_declaration (vdecl); } else { function = new CCodeFunction (acc.get_cname (), "void"); - - var vdecl = new CCodeDeclaration ("void"); - vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name)); - vdecl.add_declarator (vdeclarator); - type_struct.add_declaration (vdecl); } function.add_parameter (cselfparam); - vdeclarator.add_parameter (cselfparam); if (acc.writable || acc.construction || returns_real_struct) { function.add_parameter (cvalueparam); - vdeclarator.add_parameter (cvalueparam); } - - if (!prop.is_internal_symbol () && (acc.readable || acc.writable) && acc.access != SymbolAccessibility.PRIVATE) { - // accessor function should be public if the property is a public symbol and it's not a construct-only setter - header_declarations.add_type_member_declaration (function.copy ()); - } else { + + if (prop.is_private_symbol () || !(acc.readable || acc.writable) || acc.access == SymbolAccessibility.PRIVATE) { + // accessor function should be private if the property is an internal symbol or it's a construct-only setter function.modifiers |= CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (function.copy ()); } - + var block = new CCodeBlock (); function.block = block; @@ -1292,12 +1270,9 @@ internal class Vala.CCodeBaseModule : CCodeModule { } if (!is_virtual) { - if (!prop.is_internal_symbol () && (acc.readable || acc.writable) && acc.access != SymbolAccessibility.PRIVATE) { - // accessor function should be public if the property is a public symbol and it's not a construct-only setter - header_declarations.add_type_member_declaration (function.copy ()); - } else { + if (prop.is_private_symbol () || !(acc.readable || acc.writable) || acc.access == SymbolAccessibility.PRIVATE) { + // accessor function should be private if the property is an internal symbol or it's a construct-only setter function.modifiers |= CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (function.copy ()); } } @@ -1346,7 +1321,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { } current_property_accessor = null; - current_return_type = null; + current_return_type = old_return_type; } public override void visit_destructor (Destructor d) { @@ -1475,6 +1450,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { local.accept_children (codegen); + generate_type_declaration (local.variable_type, source_declarations); + if (local.variable_type is ArrayType) { // create variables to store array dimensions var array_type = (ArrayType) local.variable_type; @@ -2331,7 +2308,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { } } - private string get_symbol_lock_name (Symbol sym) { + public string get_symbol_lock_name (Symbol sym) { return "__lock_%s".printf (sym.name); } @@ -2776,6 +2753,18 @@ internal class Vala.CCodeBaseModule : CCodeModule { } } + public virtual void generate_class_declaration (Class cl, CCodeDeclarationSpace decl_space) { + } + + public virtual void generate_interface_declaration (Interface iface, CCodeDeclarationSpace decl_space) { + } + + public virtual void generate_method_declaration (Method m, CCodeDeclarationSpace decl_space) { + } + + public virtual void generate_error_domain_declaration (ErrorDomain edomain, CCodeDeclarationSpace decl_space) { + } + public override void visit_object_creation_expression (ObjectCreationExpression expr) { expr.accept_children (codegen); @@ -2802,6 +2791,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { // NULL is an empty list expr.ccodenode = new CCodeConstant ("NULL"); } else if (expr.type_reference.data_type is Class && expr.type_reference.data_type.is_subtype_of (gobject_type)) { + generate_class_declaration ((Class) expr.type_reference.data_type, source_declarations); + creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_new")); creation_call.add_argument (new CCodeConstant (expr.type_reference.data_type.get_type_id ())); creation_call.add_argument (new CCodeConstant ("NULL")); @@ -2825,12 +2816,16 @@ internal class Vala.CCodeBaseModule : CCodeModule { var params = m.get_parameters (); CCodeFunctionCall creation_call; + generate_method_declaration (m, source_declarations); + creation_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ())); if ((st != null && !st.is_simple_type ()) && !(m.cinstance_parameter_position < 0)) { creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance)); } + generate_type_declaration (expr.type_reference, source_declarations); + var cl = expr.type_reference.data_type as Class; if (cl != null && !cl.is_compact) { foreach (DataType type_arg in expr.type_reference.get_type_arguments ()) { @@ -2962,6 +2957,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { var edomain = (ErrorDomain) ecode.parent_symbol; CCodeFunctionCall creation_call; + generate_error_domain_declaration (edomain, source_declarations); + if (expr.get_argument_list ().size == 1) { // must not be a format argument creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_error_new_literal")); @@ -3324,6 +3321,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { } public override void visit_type_check (TypeCheck expr) { + generate_type_declaration (expr.type_reference, source_declarations); + expr.ccodenode = create_type_check (expr.expression.ccodenode, expr.type_reference); } @@ -3540,6 +3539,9 @@ internal class Vala.CCodeBaseModule : CCodeModule { } else if (prop.base_interface_property != null) { base_property = prop.base_interface_property; } + + generate_property_accessor_declaration (base_property.set_accessor, source_declarations); + set_func = base_property.set_accessor.get_cname (); if (prop is DynamicProperty) { set_func = head.get_dynamic_property_setter_cname ((DynamicProperty) prop); @@ -3612,6 +3614,10 @@ internal class Vala.CCodeBaseModule : CCodeModule { return wrappers.add (wrapper_name); } + public bool add_generated_external_symbol (Symbol external_symbol) { + return generated_external_symbols.add (external_symbol); + } + public static DataType get_data_type_for_symbol (TypeSymbol sym) { DataType type = null; diff --git a/gobject/valaccodedeclarationspace.vala b/gobject/valaccodedeclarationspace.vala index 008321b32..696b0a4e0 100644 --- a/gobject/valaccodedeclarationspace.vala +++ b/gobject/valaccodedeclarationspace.vala @@ -23,14 +23,39 @@ using Gee; class Vala.CCodeDeclarationSpace { + Set declarations = new HashSet (str_hash, str_equal); Set includes = new HashSet (str_hash, str_equal); - internal CCodeFragment begin = new CCodeFragment (); internal CCodeFragment include_directives = new CCodeFragment (); internal CCodeFragment type_declaration = new CCodeFragment (); internal CCodeFragment type_definition = new CCodeFragment (); internal CCodeFragment type_member_declaration = new CCodeFragment (); internal CCodeFragment constant_declaration = new CCodeFragment (); + public bool add_declaration (string name) { + if (name in declarations) { + return true; + } + declarations.add (name); + return false; + } + + public bool add_symbol_declaration (Symbol sym, string name) { + if (add_declaration (name)) { + return true; + } + if (sym.external_package) { + // add appropriate include file + foreach (string header_filename in sym.get_cheader_filenames ()) { + add_include (header_filename); + } + // declaration complete + return true; + } else { + // require declaration + return false; + } + } + public void add_include (string filename, bool local = false) { if (!(filename in includes)) { include_directives.append (new CCodeIncludeDirective (filename, local)); @@ -38,10 +63,6 @@ class Vala.CCodeDeclarationSpace { } } - public void add_begin (CCodeNode node) { - begin.append (node); - } - public void add_type_declaration (CCodeNode node) { type_declaration.append (node); } diff --git a/gobject/valaccodedelegatemodule.vala b/gobject/valaccodedelegatemodule.vala index a5a22b47e..f7fae0ede 100644 --- a/gobject/valaccodedelegatemodule.vala +++ b/gobject/valaccodedelegatemodule.vala @@ -32,11 +32,15 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { base (codegen, next); } - public override void visit_delegate (Delegate d) { - d.accept_children (codegen); + public override void generate_delegate_declaration (Delegate d, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (d, d.get_cname ())) { + return; + } var cfundecl = new CCodeFunctionDeclarator (d.get_cname ()); foreach (FormalParameter param in d.get_parameters ()) { + generate_parameter (param, decl_space, new HashMap (), null); + cfundecl.add_parameter ((CCodeFormalParameter) param.ccodenode); // handle array parameters @@ -74,17 +78,16 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { var ctypedef = new CCodeTypeDefinition (d.return_type.get_cname (), cfundecl); - if (!d.is_internal_symbol ()) { - if (d.source_reference != null && d.source_reference.comment != null) { - header_declarations.add_type_declaration (new CCodeComment (d.source_reference.comment)); - } - header_declarations.add_type_declaration (ctypedef); - } else { - if (d.source_reference != null && d.source_reference.comment != null) { - source_declarations.add_type_declaration (new CCodeComment (d.source_reference.comment)); - } - source_declarations.add_type_declaration (ctypedef); + if (d.source_reference != null && d.source_reference.comment != null) { + decl_space.add_type_declaration (new CCodeComment (d.source_reference.comment)); } + decl_space.add_type_declaration (ctypedef); + } + + public override void visit_delegate (Delegate d) { + d.accept_children (codegen); + + generate_delegate_declaration (d, source_declarations); } public override string get_delegate_target_cname (string delegate_cname) { @@ -238,26 +241,7 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { var d_params = d.get_parameters (); foreach (FormalParameter param in d_params) { - // ensure that C code node has been generated - param.accept (codegen); - - cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode); - - // handle array parameters - if (!param.no_array_length && param.parameter_type is ArrayType) { - var array_type = (ArrayType) param.parameter_type; - - var length_ctype = "int"; - if (param.direction != ParameterDirection.IN) { - length_ctype = "int*"; - } - - for (int dim = 1; dim <= array_type.rank; dim++) { - var cparam = new CCodeFormalParameter (head.get_array_length_cname (param.name, dim), length_ctype); - cparam_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), cparam); - } - } - + generate_parameter (param, source_declarations, cparam_map, null); } if (!d.no_array_length && d.return_type is ArrayType) { // return array length if appropriate @@ -387,12 +371,20 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { return wrapper_name; } - public override void generate_parameter (FormalParameter param, Map cparam_map, Map? carg_map) { + public override void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map cparam_map, Map? carg_map) { if (!(param.parameter_type is DelegateType || param.parameter_type is MethodType)) { - base.generate_parameter (param, cparam_map, carg_map); + base.generate_parameter (param, decl_space, cparam_map, carg_map); return; } + string ctypename = param.parameter_type.get_cname (); + + if (param.direction != ParameterDirection.IN) { + ctypename += "*"; + } + + param.ccodenode = new CCodeFormalParameter (param.name, ctypename); + cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode); if (carg_map != null) { carg_map.set (get_param_pos (param.cparameter_position), new CCodeIdentifier (param.name)); @@ -401,6 +393,9 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { if (param.parameter_type is DelegateType) { var deleg_type = (DelegateType) param.parameter_type; var d = deleg_type.delegate_symbol; + + generate_delegate_declaration (d, decl_space); + if (d.has_target) { var cparam = new CCodeFormalParameter (get_delegate_target_cname (param.name), "void*"); cparam_map.set (get_param_pos (param.cdelegate_target_parameter_position), cparam); diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index 0ada7dbd6..9d9b3c851 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -76,18 +76,10 @@ public class Vala.CCodeGenerator : CodeGenerator { head.visit_enum (en); } - public override void visit_enum_value (EnumValue ev) { - head.visit_enum_value (ev); - } - public override void visit_error_domain (ErrorDomain edomain) { head.visit_error_domain (edomain); } - public override void visit_error_code (ErrorCode ecode) { - head.visit_error_code (ecode); - } - public override void visit_delegate (Delegate d) { head.visit_delegate (d); } diff --git a/gobject/valaccodememberaccessmodule.vala b/gobject/valaccodememberaccessmodule.vala index d2731e8af..8b618acc5 100644 --- a/gobject/valaccodememberaccessmodule.vala +++ b/gobject/valaccodememberaccessmodule.vala @@ -45,7 +45,19 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { if (expr.symbol_reference is Method) { var m = (Method) expr.symbol_reference; - + + if (!(m is DynamicMethod || m is ArrayMoveMethod || m is ArrayResizeMethod)) { + generate_method_declaration (m, source_declarations); + + if (!m.external && m.external_package) { + // internal VAPI methods + // only add them once per source file + if (add_generated_external_symbol (m)) { + visit_method (m); + } + } + } + if (expr.inner is BaseAccess) { if (m.base_method != null) { var base_class = (Class) m.base_method.parent_symbol; @@ -103,6 +115,9 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { if (is_gtypeinstance && f.access == SymbolAccessibility.PRIVATE) { inst = new CCodeMemberAccess.pointer (pub_inst, "priv"); } else { + if (cl != null) { + generate_class_struct_declaration (cl, source_declarations); + } inst = pub_inst; } if (instance_target_type.data_type.is_reference_type () || (expr.inner != null && expr.inner.value_type is PointerType)) { @@ -149,6 +164,8 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { } else if (expr.symbol_reference is Constant) { var c = (Constant) expr.symbol_reference; + generate_constant_declaration (c, source_declarations); + string fn = c.get_full_name (); if (fn == "GLib.Log.FILE") { string s = Path.get_basename (expr.source_reference.file.filename); @@ -168,6 +185,18 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { } else if (expr.symbol_reference is Property) { var prop = (Property) expr.symbol_reference; + if (!(prop is DynamicProperty)) { + generate_property_accessor_declaration (prop.get_accessor, source_declarations); + + if (!prop.external && prop.external_package) { + // internal VAPI properties + // only add them once per source file + if (add_generated_external_symbol (prop)) { + visit_property (prop); + } + } + } + if (expr.inner is BaseAccess) { if (prop.base_property != null) { var base_class = (Class) prop.base_property.parent_symbol; diff --git a/gobject/valaccodemethodcallmodule.vala b/gobject/valaccodemethodcallmodule.vala index f77aaaf64..478512051 100644 --- a/gobject/valaccodemethodcallmodule.vala +++ b/gobject/valaccodemethodcallmodule.vala @@ -60,6 +60,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule { // constructor var cl = (Class) ((ObjectType) itype).type_symbol; m = cl.default_construction_method; + generate_method_declaration (m, source_declarations); ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ())); } diff --git a/gobject/valaccodemethodmodule.vala b/gobject/valaccodemethodmodule.vala index 5096111d7..3aab9ec6b 100644 --- a/gobject/valaccodemethodmodule.vala +++ b/gobject/valaccodemethodmodule.vala @@ -66,10 +66,10 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { return result; } - public virtual void generate_method_result_declaration (Method m, CCodeFunction cfunc, Map cparam_map, Map? carg_map) { + public virtual void generate_method_result_declaration (Method m, CCodeDeclarationSpace decl_space, CCodeFunction cfunc, Map cparam_map, Map? carg_map) { var creturn_type = m.return_type; if (m is CreationMethod) { - var cl = current_type_symbol as Class; + var cl = m.parent_symbol as Class; if (cl != null) { // object creation methods return the new object in C // in Vala they have no return type @@ -78,6 +78,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { } cfunc.return_type = get_creturn_type (m, creturn_type.get_cname ()); + generate_type_declaration (m.return_type, decl_space); + if (!m.no_array_length && m.return_type is ArrayType) { // return array length if appropriate var array_type = (ArrayType) m.return_type; @@ -140,6 +142,42 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { return complete_block; } + public override void generate_method_declaration (Method m, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (m, m.get_cname ())) { + return; + } + + var function = new CCodeFunction (m.get_cname ()); + + if (m.is_private_symbol ()) { + function.modifiers |= CCodeModifiers.STATIC; + if (m.is_inline) { + function.modifiers |= CCodeModifiers.INLINE; + } + } + + var cparam_map = new HashMap (direct_hash, direct_equal); + var carg_map = new HashMap (direct_hash, direct_equal); + + generate_cparameters (m, decl_space, cparam_map, function, null, carg_map, new CCodeFunctionCall (new CCodeIdentifier ("fake"))); + + decl_space.add_type_member_declaration (function); + + if (m is CreationMethod && m.parent_symbol is Class) { + // _construct function + function = new CCodeFunction (m.get_real_cname ()); + + if (m.is_private_symbol ()) { + function.modifiers |= CCodeModifiers.STATIC; + } + + cparam_map = new HashMap (direct_hash, direct_equal); + generate_cparameters (m, decl_space, cparam_map, function); + + decl_space.add_type_member_declaration (function); + } + } + public override void visit_method (Method m) { var old_type_symbol = current_type_symbol; var old_symbol = current_symbol; @@ -249,6 +287,16 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { variable_name_map = old_variable_name_map; current_try = old_try; + // do not declare overriding methods and interface implementations + if (m.is_abstract || m.is_virtual + || (m.base_method == null && m.base_interface_method == null)) { + generate_method_declaration (m, source_declarations); + + if (!m.is_internal_symbol ()) { + generate_method_declaration (m, header_declarations); + } + } + function = new CCodeFunction (m.get_real_cname ()); m.ccodenode = function; @@ -258,30 +306,17 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { var cparam_map = new HashMap (direct_hash, direct_equal); - CCodeFunctionDeclarator vdeclarator = null; - if ((m.is_abstract || m.is_virtual) && !m.coroutine) { - var vdecl = new CCodeDeclaration (get_creturn_type (m, creturn_type.get_cname ())); - vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name); - vdecl.add_declarator (vdeclarator); - type_struct.add_declaration (vdecl); - } - - generate_cparameters (m, cparam_map, function, vdeclarator); - - bool visible = !m.is_internal_symbol (); + generate_cparameters (m, source_declarations, cparam_map, function); // generate *_real_* functions for virtual methods // also generate them for abstract methods of classes to prevent faulty subclassing if (!m.is_abstract || (m.is_abstract && current_type_symbol is Class)) { - if (visible && m.base_method == null && m.base_interface_method == null) { - /* public methods need function declaration in - * header file except virtual/overridden methods */ - header_declarations.add_type_member_declaration (function.copy ()); - } else { - /* declare all other functions in source file to - * avoid dependency on order within source file */ + if (m.base_method != null || m.base_interface_method != null) { + // declare *_real_* function function.modifiers |= CCodeModifiers.STATIC; source_declarations.add_type_member_declaration (function.copy ()); + } else if (m.is_private_symbol ()) { + function.modifiers |= CCodeModifiers.STATIC; } /* Methods imported from a plain C file don't @@ -583,14 +618,43 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { } } - public virtual void generate_parameter (FormalParameter param, Map cparam_map, Map? carg_map) { + public virtual void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map cparam_map, Map? carg_map) { + if (!param.ellipsis) { + string ctypename = param.parameter_type.get_cname (); + + generate_type_declaration (param.parameter_type, decl_space); + + // pass non-simple structs always by reference + if (param.parameter_type.data_type is Struct) { + var st = (Struct) param.parameter_type.data_type; + generate_struct_declaration (st, decl_space); + if (!st.is_simple_type () && param.direction == ParameterDirection.IN) { + if (st.use_const) { + ctypename = "const " + ctypename; + } + + if (!param.parameter_type.nullable) { + ctypename += "*"; + } + } + } + + if (param.direction != ParameterDirection.IN) { + ctypename += "*"; + } + + param.ccodenode = new CCodeFormalParameter (param.name, ctypename); + } else { + param.ccodenode = new CCodeFormalParameter.with_ellipsis (); + } + cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode); - if (carg_map != null) { + if (carg_map != null && !param.ellipsis) { carg_map.set (get_param_pos (param.cparameter_position), new CCodeIdentifier (param.name)); } } - public override void generate_cparameters (Method m, Map cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) { + public override void generate_cparameters (Method m, CCodeDeclarationSpace decl_space, Map cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) { if (m.parent_symbol is Class && m is CreationMethod) { var cl = (Class) m.parent_symbol; if (!cl.is_compact && vcall == null) { @@ -611,6 +675,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { assert_not_reached (); } + generate_type_declaration (this_type, decl_space); + CCodeFormalParameter instance_param = null; if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) { var base_type = new ObjectType ((Interface) m.base_interface_method.parent_symbol); @@ -637,7 +703,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { if (is_gtypeinstance_creation_method (m)) { // memory management for generic types int type_param_index = 0; - foreach (TypeParameter type_param in current_class.get_type_parameters ()) { + var cl = (Class) m.parent_symbol; + foreach (TypeParameter type_param in cl.get_type_parameters ()) { cparam_map.set (get_param_pos (0.1 * type_param_index + 0.01), new CCodeFormalParameter ("%s_type".printf (type_param.name.down ()), "GType")); cparam_map.set (get_param_pos (0.1 * type_param_index + 0.02), new CCodeFormalParameter ("%s_dup_func".printf (type_param.name.down ()), "GBoxedCopyFunc")); cparam_map.set (get_param_pos (0.1 * type_param_index + 0.03), new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify")); @@ -663,11 +730,11 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { } } - generate_parameter (param, cparam_map, carg_map); + generate_parameter (param, source_declarations, cparam_map, carg_map); } if ((direction & 2) != 0) { - generate_method_result_declaration (m, func, cparam_map, carg_map); + generate_method_result_declaration (m, decl_space, func, cparam_map, carg_map); } // append C parameters in the right order @@ -688,15 +755,16 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { vdeclarator.add_parameter (cparam_map.get (min_pos)); } if (vcall != null) { - vcall.add_argument (carg_map.get (min_pos)); + var arg = carg_map.get (min_pos); + if (arg != null) { + vcall.add_argument (arg); + } } last_pos = min_pos; } } public void generate_vfunc (Method m, DataType return_type, Map cparam_map, Map carg_map, string suffix = "", int direction = 3) { - bool visible = !m.is_internal_symbol (); - var vfunc = new CCodeFunction (m.get_cname () + suffix); vfunc.line = function.line; @@ -724,7 +792,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, m.vfunc_name + suffix)); carg_map.set (get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self")); - generate_cparameters (m, cparam_map, vfunc, null, carg_map, vcall, direction); + generate_cparameters (m, source_declarations, cparam_map, vfunc, null, carg_map, vcall, direction); CCodeStatement cstmt; if (return_type is VoidType) { @@ -753,13 +821,6 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { } } - if (visible) { - header_declarations.add_type_member_declaration (vfunc.copy ()); - } else { - vfunc.modifiers |= CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (vfunc.copy ()); - } - vfunc.block = vblock; if (m.is_abstract && m.source_reference != null && m.source_reference.comment != null) { @@ -838,6 +899,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { var cdecl = new CCodeVariableDeclarator ("self"); if (chain_up) { + generate_method_declaration (cm, source_declarations); + var ccall = new CCodeFunctionCall (new CCodeIdentifier (cm.get_real_cname ())); ccall.add_argument (new CCodeIdentifier ("object_type")); cdecl.initializer = new CCodeCastExpression (ccall, "%s*".printf (cl.get_cname ())); @@ -861,7 +924,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { } public override void visit_creation_method (CreationMethod m) { - bool visible = !m.is_internal_symbol (); + bool visible = !m.is_private_symbol (); if (m.body != null && current_type_symbol is Class && current_class.is_subtype_of (gobject_type)) { int n_params = 0; @@ -898,18 +961,17 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { var vcall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ())); vcall.add_argument (new CCodeIdentifier (current_class.get_type_id ())); - generate_cparameters (m, cparam_map, vfunc, null, carg_map, vcall); + generate_cparameters (m, source_declarations, cparam_map, vfunc, null, carg_map, vcall); CCodeStatement cstmt = new CCodeReturnStatement (vcall); cstmt.line = vfunc.line; vblock.add_statement (cstmt); - if (visible) { - header_declarations.add_type_member_declaration (vfunc.copy ()); - } else { + if (!visible) { vfunc.modifiers |= CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (vfunc.copy ()); } - + + source_declarations.add_type_member_declaration (vfunc.copy ()); + vfunc.block = vblock; source_type_member_definition.append (vfunc); diff --git a/gobject/valaccodemodule.vala b/gobject/valaccodemodule.vala index 85415b097..8dff9bf5a 100644 --- a/gobject/valaccodemodule.vala +++ b/gobject/valaccodemodule.vala @@ -72,18 +72,10 @@ public abstract class Vala.CCodeModule { next.visit_enum (en); } - public virtual void visit_enum_value (EnumValue ev) { - next.visit_enum_value (ev); - } - public virtual void visit_error_domain (ErrorDomain edomain) { next.visit_error_domain (edomain); } - public virtual void visit_error_code (ErrorCode ecode) { - next.visit_error_code (ecode); - } - public virtual void visit_delegate (Delegate d) { next.visit_delegate (d); } @@ -328,10 +320,6 @@ public abstract class Vala.CCodeModule { next.visit_assignment (a); } - public virtual void generate_cparameters (Method m, Map cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) { - next.generate_cparameters (m, cparam_map, func, vdeclarator, carg_map, vcall, direction); - } - public virtual string? get_custom_creturn_type (Method m) { return next.get_custom_creturn_type (m); } diff --git a/gobject/valaccodestructmodule.vala b/gobject/valaccodestructmodule.vala index 58026085b..00a60af44 100644 --- a/gobject/valaccodestructmodule.vala +++ b/gobject/valaccodestructmodule.vala @@ -1,6 +1,7 @@ /* valaccodestructmodule.vala * - * Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini + * Copyright (C) 2006-2009 Jürg Billeter + * Copyright (C) 2006-2008 Raffaele Sandrini * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,31 +29,62 @@ internal class Vala.CCodeStructModule : CCodeBaseModule { base (codegen, next); } - public override void visit_struct (Struct st) { - var old_type_symbol = current_type_symbol; - var old_instance_struct = instance_struct; - var old_instance_finalize_fragment = instance_finalize_fragment; - current_type_symbol = st; - instance_struct = new CCodeStruct ("_%s".printf (st.get_cname ())); - instance_finalize_fragment = new CCodeFragment (); - - CCodeDeclarationSpace decl_space; - if (st.access != SymbolAccessibility.PRIVATE) { - decl_space = header_declarations; - } else { - decl_space = source_declarations; + public override void generate_struct_declaration (Struct st, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (st, st.get_cname ())) { + return; } - if (st.access == SymbolAccessibility.PRIVATE - || st.source_reference.file.cycle == null) { - // no file dependency cycle for private symbols - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ()))); + var instance_struct = new CCodeStruct ("_%s".printf (st.get_cname ())); + + foreach (Field f in st.get_fields ()) { + string field_ctype = f.field_type.get_cname (); + if (f.is_volatile) { + field_ctype = "volatile " + field_ctype; + } + + if (f.binding == MemberBinding.INSTANCE) { + instance_struct.add_field (field_ctype, f.get_cname ()); + if (f.field_type is ArrayType && !f.no_array_length) { + // create fields to store array dimensions + var array_type = (ArrayType) f.field_type; + var len_type = int_type.copy (); + + for (int dim = 1; dim <= array_type.rank; dim++) { + instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim)); + } + + if (array_type.rank == 1 && f.is_internal_symbol ()) { + instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name)); + } + } else if (f.field_type is DelegateType) { + var delegate_type = (DelegateType) f.field_type; + if (delegate_type.delegate_symbol.has_target) { + // create field to store delegate target + instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name)); + } + } + } } + decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ()))); + if (st.source_reference.comment != null) { decl_space.add_type_definition (new CCodeComment (st.source_reference.comment)); } decl_space.add_type_definition (instance_struct); + } + + public override void visit_struct (Struct st) { + var old_type_symbol = current_type_symbol; + var old_instance_finalize_fragment = instance_finalize_fragment; + current_type_symbol = st; + instance_finalize_fragment = new CCodeFragment (); + + generate_struct_declaration (st, source_declarations); + + if (!st.is_internal_symbol ()) { + generate_struct_declaration (st, header_declarations); + } st.accept_children (codegen); @@ -65,7 +97,6 @@ internal class Vala.CCodeStructModule : CCodeBaseModule { add_struct_free_function (st); current_type_symbol = old_type_symbol; - instance_struct = old_instance_struct; instance_finalize_fragment = old_instance_finalize_fragment; } @@ -77,11 +108,7 @@ internal class Vala.CCodeStructModule : CCodeBaseModule { function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*")); - if (st.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (function.copy ()); - } else { - source_declarations.add_type_member_declaration (function.copy ()); - } + source_declarations.add_type_member_declaration (function.copy ()); var cblock = new CCodeBlock (); @@ -125,11 +152,7 @@ internal class Vala.CCodeStructModule : CCodeBaseModule { function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*")); - if (st.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (function.copy ()); - } else { - source_declarations.add_type_member_declaration (function.copy ()); - } + source_declarations.add_type_member_declaration (function.copy ()); var cblock = new CCodeBlock (); @@ -157,11 +180,7 @@ internal class Vala.CCodeStructModule : CCodeBaseModule { function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*")); function.add_parameter (new CCodeFormalParameter ("dest", st.get_cname () + "*")); - if (st.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (function.copy ()); - } else { - source_declarations.add_type_member_declaration (function.copy ()); - } + source_declarations.add_type_member_declaration (function.copy ()); var cblock = new CCodeBlock (); var cfrag = new CCodeFragment (); @@ -208,11 +227,7 @@ internal class Vala.CCodeStructModule : CCodeBaseModule { function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*")); - if (st.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (function.copy ()); - } else { - source_declarations.add_type_member_declaration (function.copy ()); - } + source_declarations.add_type_member_declaration (function.copy ()); var cblock = new CCodeBlock (); diff --git a/gobject/valadbusclientmodule.vala b/gobject/valadbusclientmodule.vala index 77e986d99..5a5214d71 100644 --- a/gobject/valadbusclientmodule.vala +++ b/gobject/valadbusclientmodule.vala @@ -52,7 +52,7 @@ internal class Vala.DBusClientModule : DBusModule { var cparam_map = new HashMap (direct_hash, direct_equal); - generate_cparameters (method, cparam_map, func); + generate_cparameters (method, source_declarations, cparam_map, func); var block = new CCodeBlock (); if (dynamic_method.dynamic_type.data_type == dbus_object_type) { @@ -840,12 +840,9 @@ internal class Vala.DBusClientModule : DBusModule { string cname = iface.get_cname () + "DBusProxy"; string lower_cname = iface.get_lower_case_cprefix () + "dbus_proxy"; - CCodeDeclarationSpace decl_space; if (iface.access != SymbolAccessibility.PRIVATE) { - decl_space = header_declarations; dbus_glib_h_needed_in_header = true; } else { - decl_space = source_declarations; dbus_glib_h_needed = true; } @@ -922,7 +919,7 @@ internal class Vala.DBusClientModule : DBusModule { new_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("self"))); - decl_space.add_type_member_declaration (proxy_new.copy ()); + source_declarations.add_type_member_declaration (proxy_new.copy ()); proxy_new.block = new_block; source_type_member_definition.append (proxy_new); @@ -1272,7 +1269,7 @@ internal class Vala.DBusClientModule : DBusModule { var cparam_map = new HashMap (direct_hash, direct_equal); - generate_cparameters (m, cparam_map, function); + generate_cparameters (m, source_declarations, cparam_map, function); var block = new CCodeBlock (); var prefragment = new CCodeFragment (); @@ -1368,7 +1365,7 @@ internal class Vala.DBusClientModule : DBusModule { cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("callback", "GAsyncReadyCallback")); cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("user_data", "gpointer")); - generate_cparameters (m, cparam_map, function, null, null, null, 1); + generate_cparameters (m, source_declarations, cparam_map, function, null, null, null, 1); var block = new CCodeBlock (); var prefragment = new CCodeFragment (); @@ -1496,7 +1493,7 @@ internal class Vala.DBusClientModule : DBusModule { cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("res", "GAsyncResult*")); - generate_cparameters (m, cparam_map, function, null, null, null, 2); + generate_cparameters (m, source_declarations, cparam_map, function, null, null, null, 2); var block = new CCodeBlock (); var prefragment = new CCodeFragment (); diff --git a/gobject/valadbusservermodule.vala b/gobject/valadbusservermodule.vala index 26d032b61..caede6ad0 100644 --- a/gobject/valadbusservermodule.vala +++ b/gobject/valadbusservermodule.vala @@ -324,15 +324,14 @@ internal class Vala.DBusServerModule : DBusClientModule { if (!sym.is_internal_symbol ()) { dbus_glib_h_needed_in_header = true; - - header_declarations.add_type_member_declaration (cfunc.copy ()); } else { dbus_glib_h_needed = true; cfunc.modifiers |= CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (cfunc.copy ()); } + source_declarations.add_type_member_declaration (cfunc.copy ()); + var block = new CCodeBlock (); cfunc.block = block; @@ -1129,13 +1128,12 @@ internal class Vala.DBusServerModule : DBusClientModule { cfunc.add_parameter (new CCodeFormalParameter ("message", "DBusMessage*")); cfunc.add_parameter (new CCodeFormalParameter ("object", "void*")); - if (!sym.is_internal_symbol ()) { - header_declarations.add_type_member_declaration (cfunc.copy ()); - } else { + if (sym.is_internal_symbol ()) { cfunc.modifiers |= CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (cfunc.copy ()); } + source_declarations.add_type_member_declaration (cfunc.copy ()); + var block = new CCodeBlock (); cfunc.block = block; diff --git a/gobject/valagasyncmodule.vala b/gobject/valagasyncmodule.vala index c6d863a33..af2c96f18 100644 --- a/gobject/valagasyncmodule.vala +++ b/gobject/valagasyncmodule.vala @@ -159,7 +159,7 @@ internal class Vala.GAsyncModule : GSignalModule { cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("callback", "GAsyncReadyCallback")); cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("user_data", "gpointer")); - generate_cparameters (m, cparam_map, asyncfunc, null, null, null, 1); + generate_cparameters (m, source_declarations, cparam_map, asyncfunc, null, null, null, 1); if (!m.is_internal_symbol () && m.base_method == null && m.base_interface_method == null) { asyncfunc.modifiers |= CCodeModifiers.STATIC; @@ -181,11 +181,7 @@ internal class Vala.GAsyncModule : GSignalModule { var block = function.block; function.block = null; - if ((function.modifiers & CCodeModifiers.STATIC) != 0) { - source_declarations.add_type_member_declaration (function.copy ()); - } else { - header_declarations.add_type_member_declaration (function.copy ()); - } + source_declarations.add_type_member_declaration (function.copy ()); function.block = block; source_type_member_definition.append (function); @@ -214,11 +210,6 @@ internal class Vala.GAsyncModule : GSignalModule { base.visit_method (m); closure_struct = null; } - - if (m.is_abstract || m.is_virtual) { - append_async_virtual_function (m); - append_finish_virtual_function (m); - } } else { base.visit_method (m); } @@ -234,7 +225,7 @@ internal class Vala.GAsyncModule : GSignalModule { cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("res", "GAsyncResult*")); - generate_cparameters (m, cparam_map, finishfunc, null, null, null, 2); + generate_cparameters (m, source_declarations, cparam_map, finishfunc, null, null, null, 2); finishfunc.block = finishblock; @@ -271,7 +262,19 @@ internal class Vala.GAsyncModule : GSignalModule { return readyfunc; } - void append_async_virtual_function (Method m) { + public override void generate_virtual_method_declaration (Method m, CCodeDeclarationSpace decl_space, CCodeStruct type_struct) { + if (!m.coroutine) { + base.generate_virtual_method_declaration (m, decl_space, type_struct); + return; + } + + if (m.is_abstract || m.is_virtual) { + append_async_virtual_function (m, decl_space, type_struct); + append_finish_virtual_function (m, decl_space, type_struct); + } + } + + void append_async_virtual_function (Method m, CCodeDeclarationSpace decl_space, CCodeStruct type_struct) { var cparam_map = new HashMap (direct_hash, direct_equal); var carg_map = new HashMap (direct_hash, direct_equal); @@ -288,10 +291,10 @@ internal class Vala.GAsyncModule : GSignalModule { type_struct.add_declaration (vdecl); var fake = new CCodeFunction ("fake", "void"); - generate_cparameters (m, cparam_map, fake, vdeclarator, null, null, 1); + generate_cparameters (m, decl_space, cparam_map, fake, vdeclarator, null, null, 1); } - void append_finish_virtual_function (Method m) { + void append_finish_virtual_function (Method m, CCodeDeclarationSpace decl_space, CCodeStruct type_struct) { var cparam_map = new HashMap (direct_hash, direct_equal); var carg_map = new HashMap (direct_hash, direct_equal); @@ -306,7 +309,7 @@ internal class Vala.GAsyncModule : GSignalModule { type_struct.add_declaration (vdecl); var fake = new CCodeFunction ("fake", "void"); - generate_cparameters (m, cparam_map, fake, vdeclarator, null, null, 2); + generate_cparameters (m, decl_space, cparam_map, fake, vdeclarator, null, null, 2); } public override void visit_yield_statement (YieldStatement stmt) { diff --git a/gobject/valagerrormodule.vala b/gobject/valagerrormodule.vala index 01b6e14f3..5d1201c7a 100644 --- a/gobject/valagerrormodule.vala +++ b/gobject/valagerrormodule.vala @@ -1,6 +1,6 @@ /* valagerrormodule.vala * - * Copyright (C) 2008 Jürg Billeter + * Copyright (C) 2008-2009 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,20 +32,41 @@ internal class Vala.GErrorModule : CCodeDelegateModule { base (codegen, next); } - public override void visit_error_domain (ErrorDomain edomain) { - cenum = new CCodeEnum (edomain.get_cname ()); + public override void generate_error_domain_declaration (ErrorDomain edomain, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (edomain, edomain.get_cname ())) { + return; + } - if (edomain.source_reference.comment != null) { - header_declarations.add_type_definition (new CCodeComment (edomain.source_reference.comment)); + var cenum = new CCodeEnum (edomain.get_cname ()); + + foreach (ErrorCode ecode in edomain.get_codes ()) { + if (ecode.value == null) { + cenum.add_value (new CCodeEnumValue (ecode.get_cname ())); + } else { + ecode.value.accept (codegen); + cenum.add_value (new CCodeEnumValue (ecode.get_cname (), (CCodeExpression) ecode.value.ccodenode)); + } } - header_declarations.add_type_definition (cenum); - edomain.accept_children (codegen); + if (edomain.source_reference.comment != null) { + decl_space.add_type_definition (new CCodeComment (edomain.source_reference.comment)); + } + decl_space.add_type_definition (cenum); string quark_fun_name = edomain.get_lower_case_cprefix () + "quark"; var error_domain_define = new CCodeMacroReplacement (edomain.get_upper_case_cname (), quark_fun_name + " ()"); - header_declarations.add_type_definition (error_domain_define); + decl_space.add_type_definition (error_domain_define); + + var cquark_fun = new CCodeFunction (quark_fun_name, gquark_type.data_type.get_cname ()); + + decl_space.add_type_member_declaration (cquark_fun); + } + + public override void visit_error_domain (ErrorDomain edomain) { + generate_error_domain_declaration (edomain, source_declarations); + + string quark_fun_name = edomain.get_lower_case_cprefix () + "quark"; var cquark_fun = new CCodeFunction (quark_fun_name, gquark_type.data_type.get_cname ()); var cquark_block = new CCodeBlock (); @@ -55,21 +76,10 @@ internal class Vala.GErrorModule : CCodeDelegateModule { cquark_block.add_statement (new CCodeReturnStatement (cquark_call)); - header_declarations.add_type_member_declaration (cquark_fun.copy ()); - cquark_fun.block = cquark_block; source_type_member_definition.append (cquark_fun); } - public override void visit_error_code (ErrorCode ecode) { - if (ecode.value == null) { - cenum.add_value (new CCodeEnumValue (ecode.get_cname ())); - } else { - ecode.value.accept (codegen); - cenum.add_value (new CCodeEnumValue (ecode.get_cname (), (CCodeExpression) ecode.value.ccodenode)); - } - } - public override void visit_throw_statement (ThrowStatement stmt) { stmt.accept_children (codegen); diff --git a/gobject/valagobjectmodule.vala b/gobject/valagobjectmodule.vala index 030c18bab..39810a494 100644 --- a/gobject/valagobjectmodule.vala +++ b/gobject/valagobjectmodule.vala @@ -32,70 +32,42 @@ internal class Vala.GObjectModule : GTypeModule { base (codegen, next); } - public override void generate_parameter (FormalParameter param, Map cparam_map, Map? carg_map) { + public override void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map cparam_map, Map? carg_map) { if (!(param.parameter_type is ObjectType)) { - base.generate_parameter (param, cparam_map, carg_map); + base.generate_parameter (param, decl_space, cparam_map, carg_map); return; } + generate_type_declaration (param.parameter_type, decl_space); + + string ctypename = param.parameter_type.get_cname (); + + if (param.direction != ParameterDirection.IN) { + ctypename += "*"; + } + + param.ccodenode = new CCodeFormalParameter (param.name, ctypename); + cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode); if (carg_map != null) { carg_map.set (get_param_pos (param.cparameter_position), new CCodeIdentifier (param.name)); } } - public override void visit_class (Class cl) { - var old_symbol = current_symbol; - var old_type_symbol = current_type_symbol; - var old_class = current_class; - var old_instance_struct = instance_struct; - var old_param_spec_struct = param_spec_struct; - var old_type_struct = type_struct; - var old_instance_priv_struct = instance_priv_struct; - var old_type_priv_struct = type_priv_struct; - var old_prop_enum = prop_enum; - var old_class_init_fragment = class_init_fragment; - var old_base_init_fragment = base_init_fragment; - var old_class_finalize_fragment = class_finalize_fragment; - var old_base_finalize_fragment = base_finalize_fragment; - var old_instance_init_fragment = instance_init_fragment; - var old_instance_finalize_fragment = instance_finalize_fragment; - current_symbol = cl; - current_type_symbol = cl; - current_class = cl; - - bool is_gtypeinstance = !cl.is_compact; - bool is_gobject = cl.is_subtype_of (gobject_type); - bool is_fundamental = is_gtypeinstance && cl.base_class == null; - - if (cl.get_cname().len () < 3) { - cl.error = true; - Report.error (cl.source_reference, "Class name `%s' is too short".printf (cl.get_cname ())); + public override void generate_class_declaration (Class cl, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (cl, cl.get_cname ())) { return; } - - instance_struct = new CCodeStruct ("_%s".printf (cl.get_cname ())); - type_struct = new CCodeStruct ("_%sClass".printf (cl.get_cname ())); - instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ())); - type_priv_struct = new CCodeStruct ("_%sClassPrivate".printf (cl.get_cname ())); - prop_enum = new CCodeEnum (); - prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null)))); - class_init_fragment = new CCodeFragment (); - base_init_fragment = new CCodeFragment (); - class_finalize_fragment = new CCodeFragment (); - base_finalize_fragment = new CCodeFragment (); - instance_init_fragment = new CCodeFragment (); - instance_finalize_fragment = new CCodeFragment (); - - - CCodeDeclarationSpace decl_space; - if (cl.access != SymbolAccessibility.PRIVATE) { - decl_space = header_declarations; - } else { - decl_space = source_declarations; + if (cl.base_class != null) { + // base class declaration + // necessary for ref and unref function declarations + generate_class_declaration (cl.base_class, decl_space); } + bool is_gtypeinstance = !cl.is_compact; + bool is_fundamental = is_gtypeinstance && cl.base_class == null; + if (is_gtypeinstance) { decl_space.add_type_declaration (new CCodeNewline ()); var macro = "(%s_get_type ())".printf (cl.get_lower_case_cname (null)); @@ -118,13 +90,93 @@ internal class Vala.GObjectModule : GTypeModule { decl_space.add_type_declaration (new CCodeNewline ()); } + decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ()))); + + if (is_fundamental) { + var ref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "ref", "gpointer"); + var unref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "unref", "void"); + if (cl.access == SymbolAccessibility.PRIVATE) { + ref_fun.modifiers = CCodeModifiers.STATIC; + unref_fun.modifiers = CCodeModifiers.STATIC; + } + + ref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer")); + unref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer")); + + decl_space.add_type_member_declaration (ref_fun.copy ()); + decl_space.add_type_member_declaration (unref_fun.copy ()); + + // GParamSpec and GValue functions + var function_name = cl.get_lower_case_cname ("param_spec_"); + + var function = new CCodeFunction (function_name, "GParamSpec*"); + function.add_parameter (new CCodeFormalParameter ("name", "const gchar*")); + function.add_parameter (new CCodeFormalParameter ("nick", "const gchar*")); + function.add_parameter (new CCodeFormalParameter ("blurb", "const gchar*")); + function.add_parameter (new CCodeFormalParameter ("object_type", "GType")); + function.add_parameter (new CCodeFormalParameter ("flags", "GParamFlags")); - if (cl.access == SymbolAccessibility.PRIVATE - || cl.source_reference.file.cycle == null) { - // no file dependency cycle for private symbols - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (instance_struct.name), new CCodeVariableDeclarator (cl.get_cname ()))); + cl.set_param_spec_function (function_name); + + if (cl.access == SymbolAccessibility.PRIVATE) { + function.modifiers = CCodeModifiers.STATIC; + } + + decl_space.add_type_member_declaration (function); + + function = new CCodeFunction (cl.get_set_value_function (), "void"); + function.add_parameter (new CCodeFormalParameter ("value", "GValue*")); + function.add_parameter (new CCodeFormalParameter ("v_object", "gpointer")); + + if (cl.access == SymbolAccessibility.PRIVATE) { + function.modifiers = CCodeModifiers.STATIC; + } + + decl_space.add_type_member_declaration (function); + + function = new CCodeFunction (cl.get_get_value_function (), "gpointer"); + function.add_parameter (new CCodeFormalParameter ("value", "const GValue*")); + + if (cl.access == SymbolAccessibility.PRIVATE) { + function.modifiers = CCodeModifiers.STATIC; + } + + decl_space.add_type_member_declaration (function); + } + + if (is_gtypeinstance) { + decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%sClass".printf (cl.get_cname ()), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ())))); + + var type_fun = new ClassRegisterFunction (cl, context); + type_fun.init_from_type (in_plugin); + decl_space.add_type_member_declaration (type_fun.get_declaration ()); + } + } + + public override void generate_class_struct_declaration (Class cl, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (cl, "struct _" + cl.get_cname ())) { + return; } + if (cl.base_class != null) { + // base class declaration + generate_class_struct_declaration (cl.base_class, decl_space); + } + foreach (DataType base_type in cl.get_base_types ()) { + var iface = base_type.data_type as Interface; + if (iface != null) { + generate_interface_declaration (iface, decl_space); + } + } + + generate_class_declaration (cl, decl_space); + + bool is_gtypeinstance = !cl.is_compact; + bool is_fundamental = is_gtypeinstance && cl.base_class == null; + + var instance_struct = new CCodeStruct ("_%s".printf (cl.get_cname ())); + var type_struct = new CCodeStruct ("_%sClass".printf (cl.get_cname ())); + if (cl.base_class != null) { instance_struct.add_field (cl.base_class.get_cname (), "parent_instance"); } else if (is_fundamental) { @@ -138,19 +190,7 @@ internal class Vala.GObjectModule : GTypeModule { } if (is_gtypeinstance) { - if (cl.access == SymbolAccessibility.PRIVATE - || cl.source_reference.file.cycle == null) { - // no file dependency cycle for private symbols - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ())))); - } - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ())))); - if (cl.has_class_private_fields) { - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ())))); - var cdecl = new CCodeDeclaration ("GQuark"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ()), new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC; - decl_space.add_type_declaration (cdecl); - } + decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %sPrivate".printf (instance_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ())))); instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv"); if (is_fundamental) { @@ -171,20 +211,246 @@ internal class Vala.GObjectModule : GTypeModule { if (is_gtypeinstance) { decl_space.add_type_definition (type_struct); + } + + foreach (Method m in cl.get_methods ()) { + generate_virtual_method_declaration (m, decl_space, type_struct); + } + + foreach (Property prop in cl.get_properties ()) { + if (!prop.is_abstract && !prop.is_virtual) { + continue; + } + + var t = (ObjectTypeSymbol) prop.parent_symbol; + + bool returns_real_struct = prop.property_type.is_real_struct_type (); + + var this_type = new ObjectType (t); + var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ()); + CCodeFormalParameter cvalueparam; + if (returns_real_struct) { + cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname () + "*"); + } else { + cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname ()); + } + + if (prop.get_accessor != null) { + var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name)); + vdeclarator.add_parameter (cselfparam); + string creturn_type; + if (returns_real_struct) { + vdeclarator.add_parameter (cvalueparam); + creturn_type = "void"; + } else { + creturn_type = prop.property_type.get_cname (); + } + var vdecl = new CCodeDeclaration (creturn_type); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); + } + if (prop.set_accessor != null) { + var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name)); + vdeclarator.add_parameter (cselfparam); + vdeclarator.add_parameter (cvalueparam); + var vdecl = new CCodeDeclaration ("void"); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); + } + } + + foreach (Field f in cl.get_fields ()) { + string field_ctype = f.field_type.get_cname (); + if (f.is_volatile) { + field_ctype = "volatile " + field_ctype; + } + + if (f.binding == MemberBinding.INSTANCE && f.access != SymbolAccessibility.PRIVATE) { + generate_type_declaration (f.field_type, decl_space); + + instance_struct.add_field (field_ctype, f.get_cname ()); + if (f.field_type is ArrayType && !f.no_array_length) { + // create fields to store array dimensions + var array_type = (ArrayType) f.field_type; + var len_type = int_type.copy (); + + for (int dim = 1; dim <= array_type.rank; dim++) { + instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim)); + } + + if (array_type.rank == 1 && f.is_internal_symbol ()) { + instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name)); + } + } else if (f.field_type is DelegateType) { + var delegate_type = (DelegateType) f.field_type; + if (delegate_type.delegate_symbol.has_target) { + // create field to store delegate target + instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name)); + } + } + } else if (f.binding == MemberBinding.CLASS && f.access != SymbolAccessibility.PRIVATE) { + type_struct.add_field (field_ctype, f.get_cname ()); + } + } + } + + public virtual void generate_virtual_method_declaration (Method m, CCodeDeclarationSpace decl_space, CCodeStruct type_struct) { + if (!m.is_abstract && !m.is_virtual) { + return; + } + + // add vfunc field to the type struct + var vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name); + var cparam_map = new HashMap (direct_hash, direct_equal); + + generate_cparameters (m, decl_space, cparam_map, new CCodeFunction ("fake"), vdeclarator); + + var vdecl = new CCodeDeclaration (m.return_type.get_cname ()); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); + } + + void generate_class_private_declaration (Class cl, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (cl, cl.get_cname () + "Private")) { + return; + } + + bool is_gtypeinstance = !cl.is_compact; + + var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ())); + var type_priv_struct = new CCodeStruct ("_%sClassPrivate".printf (cl.get_cname ())); + + if (is_gtypeinstance) { + /* create type, dup_func, and destroy_func fields for generic types */ + foreach (TypeParameter type_param in cl.get_type_parameters ()) { + string func_name; + + func_name = "%s_type".printf (type_param.name.down ()); + instance_priv_struct.add_field ("GType", func_name); + + func_name = "%s_dup_func".printf (type_param.name.down ()); + instance_priv_struct.add_field ("GBoxedCopyFunc", func_name); + + func_name = "%s_destroy_func".printf (type_param.name.down ()); + instance_priv_struct.add_field ("GDestroyNotify", func_name); + } + } + + foreach (Field f in cl.get_fields ()) { + string field_ctype = f.field_type.get_cname (); + if (f.is_volatile) { + field_ctype = "volatile " + field_ctype; + } + + if (f.binding == MemberBinding.INSTANCE && f.access == SymbolAccessibility.PRIVATE) { + generate_type_declaration (f.field_type, decl_space); + + instance_priv_struct.add_field (field_ctype, f.get_cname ()); + if (f.field_type is ArrayType && !f.no_array_length) { + // create fields to store array dimensions + var array_type = (ArrayType) f.field_type; + var len_type = int_type.copy (); + + for (int dim = 1; dim <= array_type.rank; dim++) { + instance_priv_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim)); + } + + if (array_type.rank == 1 && f.is_internal_symbol ()) { + instance_priv_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name)); + } + } else if (f.field_type is DelegateType) { + var delegate_type = (DelegateType) f.field_type; + if (delegate_type.delegate_symbol.has_target) { + // create field to store delegate target + instance_priv_struct.add_field ("gpointer", get_delegate_target_cname (f.name)); + } + } + + if (f.get_lock_used ()) { + // add field for mutex + instance_priv_struct.add_field (mutex_type.get_cname (), get_symbol_lock_name (f)); + } + } else if (f.binding == MemberBinding.CLASS && f.access == SymbolAccessibility.PRIVATE) { + type_priv_struct.add_field (field_ctype, f.get_cname ()); + } + } + + if (is_gtypeinstance) { + if (cl.has_class_private_fields) { + decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ())))); + var cdecl = new CCodeDeclaration ("GQuark"); + cdecl.add_declarator (new CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ()), new CCodeConstant ("0"))); + cdecl.modifiers = CCodeModifiers.STATIC; + decl_space.add_type_declaration (cdecl); + } + /* only add the *Private struct if it is not empty, i.e. we actually have private data */ if (cl.has_private_fields || cl.get_type_parameters ().size > 0) { - source_declarations.add_type_member_declaration (instance_priv_struct); + decl_space.add_type_definition (instance_priv_struct); var macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_type_id (), cl.get_cname ()); - source_declarations.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro)); + decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro)); } if (cl.has_class_private_fields) { - source_declarations.add_type_member_declaration (type_priv_struct); - + decl_space.add_type_member_declaration (type_priv_struct); + var macro = "((%sClassPrivate *) g_type_get_qdata (type, _vala_%s_class_private_quark))".printf (cl.get_cname(), cl.get_lower_case_cname ()); - source_declarations.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_CLASS_PRIVATE(type)".printf (cl.get_upper_case_cname (null)), macro)); + decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_CLASS_PRIVATE(type)".printf (cl.get_upper_case_cname (null)), macro)); + } + decl_space.add_type_member_declaration (prop_enum); + } else { + var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void"); + if (cl.access == SymbolAccessibility.PRIVATE) { + function.modifiers = CCodeModifiers.STATIC; } - source_declarations.add_type_member_declaration (prop_enum); + + function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*")); + + decl_space.add_type_member_declaration (function); + } + } + + public override void visit_class (Class cl) { + var old_symbol = current_symbol; + var old_type_symbol = current_type_symbol; + var old_class = current_class; + var old_param_spec_struct = param_spec_struct; + var old_prop_enum = prop_enum; + var old_class_init_fragment = class_init_fragment; + var old_base_init_fragment = base_init_fragment; + var old_class_finalize_fragment = class_finalize_fragment; + var old_base_finalize_fragment = base_finalize_fragment; + var old_instance_init_fragment = instance_init_fragment; + var old_instance_finalize_fragment = instance_finalize_fragment; + current_symbol = cl; + current_type_symbol = cl; + current_class = cl; + + bool is_gtypeinstance = !cl.is_compact; + bool is_gobject = cl.is_subtype_of (gobject_type); + bool is_fundamental = is_gtypeinstance && cl.base_class == null; + + if (cl.get_cname().len () < 3) { + cl.error = true; + Report.error (cl.source_reference, "Class name `%s' is too short".printf (cl.get_cname ())); + return; + } + + prop_enum = new CCodeEnum (); + prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null)))); + class_init_fragment = new CCodeFragment (); + base_init_fragment = new CCodeFragment (); + class_finalize_fragment = new CCodeFragment (); + base_finalize_fragment = new CCodeFragment (); + instance_init_fragment = new CCodeFragment (); + instance_finalize_fragment = new CCodeFragment (); + + + generate_class_struct_declaration (cl, source_declarations); + generate_class_private_declaration (cl, source_declarations); + + if (!cl.is_internal_symbol ()) { + generate_class_struct_declaration (cl, header_declarations); } cl.accept_children (codegen); @@ -193,9 +459,9 @@ internal class Vala.GObjectModule : GTypeModule { if (is_fundamental) { param_spec_struct = new CCodeStruct ( "_%sParamSpec%s".printf(cl.parent_symbol.get_cprefix (), cl.name)); param_spec_struct.add_field ("GParamSpec", "parent_instance"); - decl_space.add_type_definition (param_spec_struct); + source_declarations.add_type_definition (param_spec_struct); - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (param_spec_struct.name), new CCodeVariableDeclarator ( "%sParamSpec%s".printf(cl.parent_symbol.get_cprefix (), cl.name)))); + source_declarations.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (param_spec_struct.name), new CCodeVariableDeclarator ( "%sParamSpec%s".printf(cl.parent_symbol.get_cprefix (), cl.name)))); gvaluecollector_h_needed = true; @@ -249,11 +515,6 @@ internal class Vala.GObjectModule : GTypeModule { var type_fun = new ClassRegisterFunction (cl, context); type_fun.init_from_type (in_plugin); - if (cl.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (type_fun.get_declaration ()); - } else { - source_declarations.add_type_member_declaration (type_fun.get_declaration ()); - } source_type_member_definition.append (type_fun.get_definition ()); if (in_plugin) { @@ -274,14 +535,6 @@ internal class Vala.GObjectModule : GTypeModule { ref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer")); unref_fun.add_parameter (new CCodeFormalParameter ("instance", "gpointer")); - if (cl.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (ref_fun.copy ()); - header_declarations.add_type_member_declaration (unref_fun.copy ()); - } else { - source_declarations.add_type_member_declaration (ref_fun.copy ()); - source_declarations.add_type_member_declaration (unref_fun.copy ()); - } - var ref_block = new CCodeBlock (); var unref_block = new CCodeBlock (); @@ -334,12 +587,6 @@ internal class Vala.GObjectModule : GTypeModule { function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*")); - if (cl.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (function.copy ()); - } else { - source_declarations.add_type_member_declaration (function.copy ()); - } - var cblock = new CCodeBlock (); cblock.add_statement (instance_finalize_fragment); @@ -361,11 +608,7 @@ internal class Vala.GObjectModule : GTypeModule { current_symbol = old_symbol; current_type_symbol = old_type_symbol; current_class = old_class; - instance_struct = old_instance_struct; param_spec_struct = old_param_spec_struct; - type_struct = old_type_struct; - instance_priv_struct = old_instance_priv_struct; - type_priv_struct = old_type_priv_struct; prop_enum = old_prop_enum; class_init_fragment = old_class_init_fragment; base_init_fragment = old_base_init_fragment; @@ -594,9 +837,6 @@ internal class Vala.GObjectModule : GTypeModule { if (cl.access == SymbolAccessibility.PRIVATE) { function.modifiers = CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (function.copy ()); - } else { - header_declarations.add_type_member_declaration (function.copy ()); } var init_block = new CCodeBlock (); @@ -639,9 +879,6 @@ internal class Vala.GObjectModule : GTypeModule { if (cl.access == SymbolAccessibility.PRIVATE) { function.modifiers = CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (function.copy ()); - } else { - header_declarations.add_type_member_declaration (function.copy ()); } var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer"); @@ -715,9 +952,6 @@ internal class Vala.GObjectModule : GTypeModule { if (cl.access == SymbolAccessibility.PRIVATE) { function.modifiers = CCodeModifiers.STATIC; - source_declarations.add_type_member_declaration (function.copy ()); - } else { - header_declarations.add_type_member_declaration (function.copy ()); } var vpointer = new CCodeMemberAccess(new CCodeMemberAccess.pointer (new CCodeIdentifier ("value"), "data[0]"),"v_pointer"); @@ -967,8 +1201,6 @@ internal class Vala.GObjectModule : GTypeModule { init_block.add_statement (new CCodeExpressionStatement (cinst)); prop_enum.add_value (new CCodeEnumValue (enum_value)); - instance_priv_struct.add_field ("GType", func_name); - func_name = "%s_dup_func".printf (type_param.name.down ()); func_name_constant = new CCodeConstant ("\"%s-dup-func\"".printf (type_param.name.down ())); @@ -985,8 +1217,6 @@ internal class Vala.GObjectModule : GTypeModule { init_block.add_statement (new CCodeExpressionStatement (cinst)); prop_enum.add_value (new CCodeEnumValue (enum_value)); - instance_priv_struct.add_field ("GBoxedCopyFunc", func_name); - func_name = "%s_destroy_func".printf (type_param.name.down ()); func_name_constant = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ())); @@ -1002,8 +1232,6 @@ internal class Vala.GObjectModule : GTypeModule { cinst.add_argument (cspec); init_block.add_statement (new CCodeExpressionStatement (cinst)); prop_enum.add_value (new CCodeEnumValue (enum_value)); - - instance_priv_struct.add_field ("GDestroyNotify", func_name); } /* create properties */ @@ -1035,20 +1263,6 @@ internal class Vala.GObjectModule : GTypeModule { init_block.add_statement (new CCodeExpressionStatement (cinst)); } } - } else if (!cl.is_compact) { - /* create type, dup_func, and destroy_func fields for generic types */ - foreach (TypeParameter type_param in cl.get_type_parameters ()) { - string func_name; - - func_name = "%s_type".printf (type_param.name.down ()); - instance_priv_struct.add_field ("GType", func_name); - - func_name = "%s_dup_func".printf (type_param.name.down ()); - instance_priv_struct.add_field ("GBoxedCopyFunc", func_name); - - func_name = "%s_destroy_func".printf (type_param.name.down ()); - instance_priv_struct.add_field ("GDestroyNotify", func_name); - } } if (!cl.is_compact) { diff --git a/gobject/valagtypemodule.vala b/gobject/valagtypemodule.vala index 42afdbb1f..4e13ccc13 100644 --- a/gobject/valagtypemodule.vala +++ b/gobject/valagtypemodule.vala @@ -1,6 +1,7 @@ /* valagtypemodule.vala * - * Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini + * Copyright (C) 2006-2009 Jürg Billeter + * Copyright (C) 2006-2008 Raffaele Sandrini * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,31 +22,29 @@ * Raffaele Sandrini */ -using GLib; +using Gee; internal class Vala.GTypeModule : GErrorModule { public GTypeModule (CCodeGenerator codegen, CCodeModule? next) { base (codegen, next); } - public override void visit_interface (Interface iface) { - current_symbol = iface; - current_type_symbol = iface; - - if (iface.get_cname().len () < 3) { - iface.error = true; - Report.error (iface.source_reference, "Interface name `%s' is too short".printf (iface.get_cname ())); + public override void generate_interface_declaration (Interface iface, CCodeDeclarationSpace decl_space) { + if (decl_space.add_symbol_declaration (iface, iface.get_cname ())) { return; } - CCodeDeclarationSpace decl_space; - if (iface.access != SymbolAccessibility.PRIVATE) { - decl_space = header_declarations; - } else { - decl_space = source_declarations; + foreach (DataType prerequisite in iface.get_prerequisites ()) { + var prereq_cl = prerequisite.data_type as Class; + var prereq_iface = prerequisite.data_type as Interface; + if (prereq_cl != null) { + generate_class_declaration (prereq_cl, decl_space); + } else if (prereq_iface != null) { + generate_interface_declaration (prereq_iface, decl_space); + } } - type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ())); + var type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ())); decl_space.add_type_declaration (new CCodeNewline ()); var macro = "(%s_get_type ())".printf (iface.get_lower_case_cname (null)); @@ -61,12 +60,9 @@ internal class Vala.GTypeModule : GErrorModule { decl_space.add_type_declaration (new CCodeMacroReplacement ("%s_GET_INTERFACE(obj)".printf (iface.get_upper_case_cname (null)), macro)); decl_space.add_type_declaration (new CCodeNewline ()); + decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ()))); + decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator (iface.get_type_cname ()))); - if (iface.source_reference.file.cycle == null) { - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ()))); - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator (iface.get_type_cname ()))); - } - type_struct.add_field ("GTypeInterface", "parent_iface"); if (iface.source_reference.comment != null) { @@ -74,17 +70,87 @@ internal class Vala.GTypeModule : GErrorModule { } decl_space.add_type_definition (type_struct); + foreach (Method m in iface.get_methods ()) { + if ((!m.is_abstract && !m.is_virtual) || m.coroutine) { + continue; + } + + // add vfunc field to the type struct + var vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name); + var cparam_map = new HashMap (direct_hash, direct_equal); + + generate_cparameters (m, decl_space, cparam_map, new CCodeFunction ("fake"), vdeclarator); + + var vdecl = new CCodeDeclaration (m.return_type.get_cname ()); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); + } + + foreach (Property prop in iface.get_properties ()) { + if (!prop.is_abstract && !prop.is_virtual) { + continue; + } + + var t = (ObjectTypeSymbol) prop.parent_symbol; + + bool returns_real_struct = prop.property_type.is_real_struct_type (); + + var this_type = new ObjectType (t); + var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ()); + CCodeFormalParameter cvalueparam; + if (returns_real_struct) { + cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname () + "*"); + } else { + cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname ()); + } + + if (prop.get_accessor != null) { + var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name)); + vdeclarator.add_parameter (cselfparam); + string creturn_type; + if (returns_real_struct) { + vdeclarator.add_parameter (cvalueparam); + creturn_type = "void"; + } else { + creturn_type = prop.property_type.get_cname (); + } + var vdecl = new CCodeDeclaration (creturn_type); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); + } + if (prop.set_accessor != null) { + var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name)); + vdeclarator.add_parameter (cselfparam); + vdeclarator.add_parameter (cvalueparam); + var vdecl = new CCodeDeclaration ("void"); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); + } + } + + var type_fun = new InterfaceRegisterFunction (iface, context); + type_fun.init_from_type (); + decl_space.add_type_member_declaration (type_fun.get_declaration ()); + } + + public override void visit_interface (Interface iface) { + current_symbol = iface; + current_type_symbol = iface; + + if (iface.get_cname().len () < 3) { + iface.error = true; + Report.error (iface.source_reference, "Interface name `%s' is too short".printf (iface.get_cname ())); + return; + } + + generate_interface_declaration (iface, source_declarations); + iface.accept_children (codegen); add_interface_base_init_function (iface); var type_fun = new InterfaceRegisterFunction (iface, context); type_fun.init_from_type (); - if (iface.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (type_fun.get_declaration ()); - } else { - source_declarations.add_type_member_declaration (type_fun.get_declaration ()); - } source_type_member_definition.append (type_fun.get_definition ()); current_type_symbol = null; @@ -143,24 +209,13 @@ internal class Vala.GTypeModule : GErrorModule { public override void visit_struct (Struct st) { base.visit_struct (st); - CCodeDeclarationSpace decl_space; - if (st.access != SymbolAccessibility.PRIVATE) { - decl_space = header_declarations; - } else { - decl_space = source_declarations; - } - - decl_space.add_type_declaration (new CCodeNewline ()); + source_declarations.add_type_declaration (new CCodeNewline ()); var macro = "(%s_get_type ())".printf (st.get_lower_case_cname (null)); - decl_space.add_type_declaration (new CCodeMacroReplacement (st.get_type_id (), macro)); + source_declarations.add_type_declaration (new CCodeMacroReplacement (st.get_type_id (), macro)); var type_fun = new StructRegisterFunction (st, context); type_fun.init_from_type (false); - if (st.access != SymbolAccessibility.PRIVATE) { - header_declarations.add_type_member_declaration (type_fun.get_declaration ()); - } else { - source_declarations.add_type_member_declaration (type_fun.get_declaration ()); - } + source_declarations.add_type_member_declaration (type_fun.get_declaration ()); source_type_member_definition.append (type_fun.get_definition ()); } } diff --git a/vala/Makefile.am b/vala/Makefile.am index 93e6f519e..dac7d4427 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -120,7 +120,6 @@ libvalacore_la_VALASOURCES = \ valasignaltype.vala \ valasizeofexpression.vala \ valasourcefile.vala \ - valasourcefilecycle.vala \ valasourcelocation.vala \ valasourcereference.vala \ valastatement.vala \ diff --git a/vala/valacastexpression.vala b/vala/valacastexpression.vala index 4f94832ce..f75c9ff90 100644 --- a/vala/valacastexpression.vala +++ b/vala/valacastexpression.vala @@ -1,6 +1,6 @@ /* valacastexpression.vala * - * Copyright (C) 2006-2008 Jürg Billeter + * Copyright (C) 2006-2009 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -114,8 +114,6 @@ public class Vala.CastExpression : Expression { // FIXME: check whether cast is allowed - analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE); - value_type = type_reference; value_type.value_owned = inner.value_type.value_owned; diff --git a/vala/valacatchclause.vala b/vala/valacatchclause.vala index 039ea6bc0..8d3d4124f 100644 --- a/vala/valacatchclause.vala +++ b/vala/valacatchclause.vala @@ -1,6 +1,6 @@ -/* valacatchvala +/* valacatchclause.vala * - * Copyright (C) 2007-2008 Jürg Billeter + * Copyright (C) 2007-2009 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -115,8 +115,6 @@ public class Vala.CatchClause : CodeNode { error_type.check (analyzer); - analyzer.current_source_file.add_type_dependency (error_type, SourceFileDependencyType.SOURCE); - body.check (analyzer); return !error; diff --git a/vala/valaclass.vala b/vala/valaclass.vala index a32abfc23..2511d1aa6 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -916,8 +916,6 @@ public class Vala.Class : ObjectTypeSymbol { Report.error (source_reference, "base type `%s` is less accessible than class `%s`".printf (base_type_reference.to_string (), get_full_name ())); return false; } - - analyzer.current_source_file.add_type_dependency (base_type_reference, SourceFileDependencyType.HEADER_FULL); } foreach (DataType type in base_types) { diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala index 184152840..e04063034 100644 --- a/vala/valacodecontext.vala +++ b/vala/valacodecontext.vala @@ -163,8 +163,6 @@ public class Vala.CodeContext { private Gee.List source_files = new ArrayList (); private Gee.List c_source_files = new ArrayList (); private Namespace _root = new Namespace (null); - - private Gee.List cycles = new ArrayList (); private Gee.List packages = new ArrayList (str_equal); @@ -294,143 +292,6 @@ public class Vala.CodeContext { file.accept (visitor); } } - - /** - * Find and resolve cycles in source file dependencies. - */ - public void find_header_cycles () { - /* find cycles in dependencies between source files */ - foreach (SourceFile file in source_files) { - /* we're only interested in internal source files */ - if (file.external_package) { - continue; - } - - if (file.mark == 0) { - visit (file, new ArrayList ()); - } - } - - /* find one head for each cycle, it must not have any - * hard dependencies on other files in the cycle - */ - foreach (SourceFileCycle cycle in cycles) { - cycle.head = find_cycle_head (cycle.files.get (0)); - cycle.head.is_cycle_head = true; - } - - /* connect the source files in a non-cyclic way - * cycle members connect to the head of their cycle - */ - foreach (SourceFile file2 in source_files) { - /* we're only interested in internal source files */ - if (file2.external_package) { - continue; - } - - foreach (SourceFile dep in file2.get_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.add_header_internal_include (file2.cycle.head.get_cinclude_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.add_header_internal_include (dep.get_cinclude_filename ()); - } - } - } - - } - - private weak SourceFile find_cycle_head (SourceFile file) { - foreach (SourceFile dep in file.get_header_internal_full_dependencies ()) { - if (dep == file) { - /* ignore file-internal dependencies */ - continue; - } - - foreach (SourceFile cycle_file in file.cycle.files) { - if (dep == cycle_file) { - return find_cycle_head (dep); - } - } - } - /* no hard dependencies on members of the same cycle found - * source file suitable as cycle head - */ - return file; - } - - private void visit (SourceFile file, Gee.List chain) { - Gee.List l = new ArrayList (); - foreach (SourceFile chain_file in chain) { - l.add (chain_file); - } - l.add (file); - - /* mark file as currently being visited */ - file.mark = 1; - - foreach (SourceFile dep in file.get_header_internal_dependencies ()) { - if (file == dep) { - continue; - } - - if (dep.mark == 1) { - /* found cycle */ - - var cycle = new SourceFileCycle (); - cycles.add (cycle); - - bool cycle_start_found = false; - foreach (SourceFile cycle_file in l) { - SourceFileCycle ref_cycle_file_cycle = cycle_file.cycle; - if (!cycle_start_found) { - if (cycle_file == dep) { - cycle_start_found = true; - } - } - - if (!cycle_start_found) { - continue; - } - - if (ref_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 */ - - cycles.remove (cycle_file.cycle); - - foreach (SourceFile inner_cycle_file in cycle_file.cycle.files) { - if (inner_cycle_file.cycle != cycle) { - /* file in inner cycle not yet added to outer cycle */ - cycle.files.add (inner_cycle_file); - inner_cycle_file.cycle = cycle; - } - } - } else { - cycle.files.add (cycle_file); - cycle_file.cycle = cycle; - } - } - } else if (dep.mark == 0) { - /* found not yet visited file */ - - visit (dep, l); - } - } - - /* mark file as successfully visited */ - file.mark = 2; - } public string? get_package_path (string pkg, string[] vapi_directories) { string basename = "%s.vapi".printf (pkg); diff --git a/vala/valaenumvalue.vala b/vala/valaenumvalue.vala index e77d7af4a..8fbcc5729 100644 --- a/vala/valaenumvalue.vala +++ b/vala/valaenumvalue.vala @@ -140,12 +140,6 @@ public class Vala.EnumValue : Symbol { if (value != null) { value.check (analyzer); - - // ensure to include dependency in header file as well if necessary - if (!parent_symbol.is_internal_symbol () - &&value is MemberAccess && value.symbol_reference != null) { - analyzer.current_source_file.add_symbol_dependency (value.symbol_reference, SourceFileDependencyType.HEADER_SHALLOW); - } } return !error; diff --git a/vala/valafield.vala b/vala/valafield.vala index 24ac796e7..f43e83bd4 100644 --- a/vala/valafield.vala +++ b/vala/valafield.vala @@ -325,16 +325,6 @@ public class Vala.Field : Member, Lockable { Report.warning (source_reference, "%s hides inherited field `%s'. Use the `new' keyword if hiding was intentional".printf (get_full_name (), get_hidden_member ().get_full_name ())); } - if (field_in_header) { - if (field_type is ValueType) { - analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.HEADER_FULL); - } else { - analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.HEADER_SHALLOW); - } - } else { - analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.SOURCE); - } - analyzer.current_source_file = old_source_file; analyzer.current_symbol = old_symbol; diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala index 621ce4b63..dde54469d 100644 --- a/vala/valaflowanalyzer.vala +++ b/vala/valaflowanalyzer.vala @@ -123,15 +123,15 @@ public class Vala.FlowAnalyzer : CodeVisitor { } public override void visit_field (Field f) { - if (f.is_library_internal_symbol () && !f.used) { + if (f.is_internal_symbol () && !f.used) { Report.warning (f.source_reference, "field `%s' never used".printf (f.get_full_name ())); } } public override void visit_method (Method m) { - if (m.is_library_internal_symbol () && !m.used && !m.entry_point - && !m.overrides && (m.base_interface_method == null || m.base_interface_method == m) - && !(m is CreationMethod)) { + if (m.is_internal_symbol () && !m.used && !m.entry_point + && !m.overrides && (m.base_interface_method == null || m.base_interface_method == m) + && !(m is CreationMethod)) { Report.warning (m.source_reference, "method `%s' never used".printf (m.get_full_name ())); } diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala index f69f38fed..91bbd8580 100644 --- a/vala/valaforeachstatement.vala +++ b/vala/valaforeachstatement.vala @@ -1,6 +1,6 @@ /* valaforeachstatement.vala * - * Copyright (C) 2006-2008 Jürg Billeter + * Copyright (C) 2006-2009 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -278,8 +278,6 @@ public class Vala.ForeachStatement : Block { return false; } - analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE); - element_variable = new LocalVariable (type_reference, variable_name); body.scope.add (variable_name, element_variable); diff --git a/vala/valaformalparameter.vala b/vala/valaformalparameter.vala index e24592a1d..021ecbe34 100644 --- a/vala/valaformalparameter.vala +++ b/vala/valaformalparameter.vala @@ -234,15 +234,6 @@ public class Vala.FormalParameter : Symbol { } if (!ellipsis) { - if (!is_internal_symbol ()) { - if (parameter_type is ValueType && !parameter_type.is_real_struct_type ()) { - analyzer.current_source_file.add_type_dependency (parameter_type, SourceFileDependencyType.HEADER_FULL); - } else { - analyzer.current_source_file.add_type_dependency (parameter_type, SourceFileDependencyType.HEADER_SHALLOW); - } - } - analyzer.current_source_file.add_type_dependency (parameter_type, SourceFileDependencyType.SOURCE); - // check whether parameter type is at least as accessible as the method if (!analyzer.is_type_accessible (this, parameter_type)) { error = true; diff --git a/vala/valainterface.vala b/vala/valainterface.vala index 66e3068e7..c048c9e79 100644 --- a/vala/valainterface.vala +++ b/vala/valainterface.vala @@ -546,8 +546,6 @@ public class Vala.Interface : ObjectTypeSymbol { Report.error (source_reference, "prerequisite `%s` is less accessible than interface `%s`".printf (prerequisite_reference.to_string (), get_full_name ())); return false; } - - analyzer.current_source_file.add_type_dependency (prerequisite_reference, SourceFileDependencyType.HEADER_FULL); } /* check prerequisites */ diff --git a/vala/valalocalvariable.vala b/vala/valalocalvariable.vala index cdc9b3a69..9fce2c2c9 100644 --- a/vala/valalocalvariable.vala +++ b/vala/valalocalvariable.vala @@ -198,8 +198,6 @@ public class Vala.LocalVariable : Symbol { } } - analyzer.current_source_file.add_type_dependency (variable_type, SourceFileDependencyType.SOURCE); - analyzer.current_symbol.scope.add (name, this); // current_symbol is a Method if this is the `result' diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala index 1ddb39d6f..4f99208cf 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -565,8 +565,6 @@ public class Vala.MemberAccess : Expression { } } - analyzer.current_source_file.add_symbol_dependency (symbol_reference, SourceFileDependencyType.SOURCE); - return !error; } diff --git a/vala/valamethod.vala b/vala/valamethod.vala index fc8ad1564..19e6c08b2 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -688,15 +688,6 @@ public class Vala.Method : Member { source_reference.file.context.module_init_method = this; } - if (!is_internal_symbol ()) { - if (return_type is ValueType) { - analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.HEADER_FULL); - } else { - analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.HEADER_SHALLOW); - } - } - analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.SOURCE); - if (return_type != null) { return_type.check (analyzer); } diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index 9d1126d81..20b829bdb 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -216,15 +216,11 @@ public class Vala.ObjectCreationExpression : Expression { foreach (DataType type_arg in type_args) { type_reference.add_type_argument (type_arg); - - analyzer.current_source_file.add_type_dependency (type_arg, SourceFileDependencyType.SOURCE); } } else { type = type_reference.data_type; } - analyzer.current_source_file.add_symbol_dependency (type, SourceFileDependencyType.SOURCE); - value_type = type_reference.copy (); value_type.value_owned = true; diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala index b138c547d..241fd3654 100644 --- a/vala/valaproperty.vala +++ b/vala/valaproperty.vala @@ -435,15 +435,6 @@ public class Vala.Property : Member, Lockable { Report.error (source_reference, "property type `%s` is less accessible than property `%s`".printf (property_type.to_string (), get_full_name ())); } - if (!is_internal_symbol ()) { - if (property_type is ValueType && !property_type.is_real_struct_type ()) { - analyzer.current_source_file.add_type_dependency (property_type, SourceFileDependencyType.HEADER_FULL); - } else { - analyzer.current_source_file.add_type_dependency (property_type, SourceFileDependencyType.HEADER_SHALLOW); - } - } - analyzer.current_source_file.add_type_dependency (property_type, SourceFileDependencyType.SOURCE); - if (overrides && base_property == null) { Report.error (source_reference, "%s: no suitable property found to override".printf (get_full_name ())); } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 7f45cc1cc..fcfdd303a 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -287,9 +287,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { break; } - /* header file necessary if we need to cast argument */ - current_source_file.add_type_dependency (param.parameter_type, SourceFileDependencyType.SOURCE); - if (param.params_array) { while (arg_it.next ()) { var arg = arg_it.get (); diff --git a/vala/valasizeofexpression.vala b/vala/valasizeofexpression.vala index 041ba4aaa..57866e3ba 100644 --- a/vala/valasizeofexpression.vala +++ b/vala/valasizeofexpression.vala @@ -1,6 +1,6 @@ /* valasizeofexpression.vala * - * Copyright (C) 2006-2008 Jürg Billeter + * Copyright (C) 2006-2009 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -80,8 +80,6 @@ public class Vala.SizeofExpression : Expression { value_type = analyzer.ulong_type; - analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE); - return !error; } } diff --git a/vala/valasourcefile.vala b/vala/valasourcefile.vala index 51466a68a..65a0e4c8b 100644 --- a/vala/valasourcefile.vala +++ b/vala/valasourcefile.vala @@ -41,29 +41,7 @@ public class Vala.SourceFile { * Specifies whether this file is a VAPI package file. */ public bool external_package { get; set; } - - /** - * Specifies the dependency cycle this source file is member of. If this - * source file is in a cycle, all type definitions of that cycle will - * only be written to the C header file of the cycle head. - */ - public SourceFileCycle cycle { get; set; } - - /** - * Specifies whether this source file is the head of the cycle, if it is - * in a cycle at all. - */ - public bool is_cycle_head { get; set; } - - /** - * Mark used for cycle detection. - * - * 0: not yet visited - * 1: currently visiting - * 2: already visited - */ - public int mark { get; set; } - + /** * The context this source file belongs to. */ @@ -84,16 +62,6 @@ public class Vala.SourceFile { private string cheader_filename = null; private string csource_filename = null; private string cinclude_filename = null; - - private Gee.List header_external_includes = new ArrayList (); - private Gee.List header_internal_includes = new ArrayList (); - private Gee.List source_external_includes = new ArrayList (); - private Gee.List source_internal_includes = new ArrayList (); - - private Gee.List header_internal_full_dependencies = new ArrayList (); - private Gee.List header_internal_dependencies = new ArrayList (); - - private Gee.Set source_symbol_dependencies = new HashSet (); private Gee.ArrayList source_array = null; @@ -260,170 +228,13 @@ public class Vala.SourceFile { */ public string get_cinclude_filename () { if (cinclude_filename == null) { - cinclude_filename = "%s%s.h".printf (get_subdir (), get_basename ()); - } - return cinclude_filename; - } - - /** - * Adds the specified symbol to the list of symbols code in this source - * file depends on. - * - * TODO Move source and header file dependency analysis to - * code generator. - * - * @param sym a symbol - * @param dep_type type of dependency - */ - public void add_symbol_dependency (Symbol? sym, SourceFileDependencyType dep_type) { - if (external_package) { - return; - } - - Symbol s; - - if (sym is ErrorCode || sym is EnumValue) { - s = sym.parent_symbol; - } else if (sym is TypeSymbol || - sym is Method || - sym is Field || - sym is Property || - sym is Constant) { - s = sym; - } else if (sym is FormalParameter) { - var fp = (FormalParameter) sym; - s = fp.parameter_type.data_type; - if (s == null) { - /* generic type parameter */ - return; - } - } else { - return; - } - - if (dep_type == SourceFileDependencyType.SOURCE) { - source_symbol_dependencies.add (s); - if (s.external_package) { - foreach (string fn in s.get_cheader_filenames ()) { - source_external_includes.add (fn); - } + if (context.header_filename != null) { + cinclude_filename = Path.get_basename (context.header_filename); } else { - foreach (string fn in s.get_cheader_filenames ()) { - source_internal_includes.add (fn); - } - } - return; - } - - if (s.external_package) { - /* external package */ - foreach (string fn in s.get_cheader_filenames ()) { - header_external_includes.add (fn); + cinclude_filename = "%s%s.h".printf (get_subdir (), get_basename ()); } - return; - } - - if (dep_type == SourceFileDependencyType.HEADER_FULL) { - foreach (string fn in s.get_cheader_filenames ()) { - header_internal_includes.add (fn); - } - header_internal_full_dependencies.add (s.source_reference.file); - } - - header_internal_dependencies.add (s.source_reference.file); - } - - /** - * Adds the symbols that define the specified type to the list of - * symbols code in this source file depends on. - * - * TODO Move source and header file dependency analysis to - * code generator. - * - * @param type a data type - * @param dep_type type of dependency - */ - public void add_type_dependency (DataType type, SourceFileDependencyType dep_type) { - foreach (Symbol type_symbol in type.get_symbols ()) { - add_symbol_dependency (type_symbol, dep_type); - } - } - - /** - * Returns the list of external includes the generated C header file - * requires. - * - * @return external include list for C header file - */ - public Gee.List get_header_external_includes () { - return new ReadOnlyList (header_external_includes); - } - - /** - * Adds the specified filename to the list of package-internal includes - * the generated C header file requires. - * - * @param include internal include for C header file - */ - public void add_header_internal_include (string include) { - /* skip includes to self */ - if (include != get_cinclude_filename ()) { - header_internal_includes.add (include); } - } - - /** - * Returns the list of package-internal includes the generated C header - * file requires. - * - * @return internal include list for C header file - */ - public Gee.List get_header_internal_includes () { - return new ReadOnlyList (header_internal_includes); - } - - /** - * Returns the list of external includes the generated C source file - * requires. - * - * @return include list for C source file - */ - public Gee.List get_source_external_includes () { - return new ReadOnlyList (source_external_includes); - } - - /** - * Returns the list of package-internal includes the generated C source - * file requires. - * - * @return include list for C source file - */ - public Gee.List get_source_internal_includes () { - return new ReadOnlyList (source_internal_includes); - } - - /** - * Returns the list of source files the generated C header file requires - * definitely. - * - * @return definite source file dependencies - */ - public Gee.List get_header_internal_full_dependencies () { - return new ReadOnlyList (header_internal_full_dependencies); - } - - /** - * Returns the list of source files the generated C header file loosely - * depends on. - * - * @return loose source file dependencies - */ - public Gee.List get_header_internal_dependencies () { - return new ReadOnlyList (header_internal_dependencies); - } - - public Gee.Set get_source_symbol_dependencies () { - return new ReadOnlySet (source_symbol_dependencies); + return cinclude_filename; } /** @@ -502,8 +313,3 @@ public class Vala.SourceFile { } } -public enum Vala.SourceFileDependencyType { - HEADER_FULL, - HEADER_SHALLOW, - SOURCE -} diff --git a/vala/valasourcefilecycle.vala b/vala/valasourcefilecycle.vala deleted file mode 100644 index b3fd4ad23..000000000 --- a/vala/valasourcefilecycle.vala +++ /dev/null @@ -1,39 +0,0 @@ -/* valasourcefilecycle.vala - * - * Copyright (C) 2006-2008 Jürg Billeter - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - */ - -using GLib; -using Gee; - -/** - * Represents a dependency cycle of source files. - */ -public class Vala.SourceFileCycle { - /** - * The members of this source file cycle. - */ - public Gee.List files = new ArrayList (); - - /** - * The head of this source file cycle. - */ - public weak SourceFile head; -} diff --git a/vala/valasymbol.vala b/vala/valasymbol.vala index 2478b14a3..61a1c0ab3 100644 --- a/vala/valasymbol.vala +++ b/vala/valasymbol.vala @@ -93,7 +93,8 @@ public abstract class Vala.Symbol : CodeNode { } for (Symbol sym = this; null != sym; sym = sym.parent_symbol) { - if (SymbolAccessibility.PRIVATE == sym.access) { + if (sym.access == SymbolAccessibility.PRIVATE + || sym.access == SymbolAccessibility.INTERNAL) { return true; } } @@ -101,10 +102,14 @@ public abstract class Vala.Symbol : CodeNode { return false; } - public bool is_library_internal_symbol () { + public bool is_private_symbol () { + if (!external && external_package) { + // non-external symbols in VAPI files are private symbols + return true; + } + for (Symbol sym = this; null != sym; sym = sym.parent_symbol) { - if (sym.access == SymbolAccessibility.PRIVATE - || sym.access == SymbolAccessibility.INTERNAL) { + if (sym.access == SymbolAccessibility.PRIVATE) { return true; } } diff --git a/vala/valatypecheck.vala b/vala/valatypecheck.vala index 2dee142f1..1f626aeb6 100644 --- a/vala/valatypecheck.vala +++ b/vala/valatypecheck.vala @@ -1,6 +1,6 @@ /* valatypecheck.vala * - * Copyright (C) 2006-2008 Jürg Billeter + * Copyright (C) 2006-2009 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -95,8 +95,6 @@ public class Vala.TypeCheck : Expression { return false; } - analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE); - value_type = analyzer.bool_type; return !error; diff --git a/vala/valatypeofexpression.vala b/vala/valatypeofexpression.vala index 9331a8f39..99d9145e3 100644 --- a/vala/valatypeofexpression.vala +++ b/vala/valatypeofexpression.vala @@ -1,6 +1,6 @@ /* valatypeofexpression.vala * - * Copyright (C) 2006-2008 Jürg Billeter + * Copyright (C) 2006-2009 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -80,8 +80,6 @@ public class Vala.TypeofExpression : Expression { value_type = analyzer.type_type; - analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE); - return !error; } }