2007-03-17 Jürg Billeter <j@bitron.ch>
+ * vala/valasemanticanalyzer.vala, vala/valacodegnerator.vala,
+ vala/valaclassregisterfunction.vala,
+ vala/valainterfaceregisterfunction.vala,
+ vala/valatyperegisterfunction.vala, vala/valacodecontext.vala: support
+ creating GTypeModule-based plug-ins with the ModuleInit attribute
+ * vala/parser.y, vala/valacodegenerator.vala, vala/valaclass.vala:
+ support static classes
+ * vapi/glib-2.0.vala: add TypePlugin and TypeModule
+
+2007-03-17 Jürg Billeter <j@bitron.ch>
+
* vala/parser.y: accept attributes without parentheses
* vala/valainterfacewriter.vala: don't write weak keyword for value
types
if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) {
vala_class_set_is_abstract (current_class, TRUE);
}
+ if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
+ vala_class_set_is_static (current_class, TRUE);
+ }
if ($8 != NULL) {
for (l = $8; l != NULL; l = l->next) {
vala_class_add_type_parameter (current_class, l->data);
* instantiated.
*/
public bool is_abstract { get; set; }
-
+
+ /**
+ * Specifies whether this class is static. Static classes may not be
+ * instantiated and may only contain static members.
+ */
+ public bool is_static { get; set; }
+
/**
* Specifies whether this class has private fields.
*/
ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer (iface_info_name, new CCodeConstant ("{ (GInterfaceInitFunc) %s_%s_interface_init, (GInterfaceFinalizeFunc) NULL, NULL}".printf (class_reference.get_lower_case_cname (null), iface.get_lower_case_cname (null)))));
frag.append (ctypedecl);
var reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_add_interface_static"));
- reg_call.add_argument (new CCodeIdentifier ("g_define_type_id"));
+ reg_call.add_argument (new CCodeIdentifier ("%s_type_id".printf (class_reference.get_lower_case_cname (null))));
reg_call.add_argument (new CCodeIdentifier (iface.get_upper_case_cname ("TYPE_")));
reg_call.add_argument (new CCodeIdentifier ("&%s".printf (iface_info_name)));
frag.append (new CCodeExpressionStatement (reg_call));
/* valacodecontext.vala
*
- * Copyright (C) 2006 Jürg Billeter
+ * Copyright (C) 2006-2007 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*/
public string library { get; set; }
+ /**
+ * Specifies the optional module initialization method.
+ */
+ public Method module_init_method { get; set; }
+
List<SourceFile> source_files;
private Symbol! root = new Symbol ();
CCodeFragment instance_init_fragment;
CCodeFragment instance_dispose_fragment;
CCodeFragment source_signal_marshaller_definition;
+ CCodeFragment module_init_fragment;
CCodeStruct instance_struct;
CCodeStruct type_struct;
DataType list_type;
DataType slist_type;
TypeReference mutex_type;
-
+ DataType type_module_type;
+
+ private bool in_plugin = false;
+ private string module_init_param_name;
+
public CodeGenerator (bool manage_memory = true) {
memory_management = manage_memory;
}
mutex_type = new TypeReference ();
mutex_type.data_type = (DataType) glib_ns.lookup ("Mutex").node;
+
+ type_module_type = (DataType) glib_ns.lookup ("TypeModule").node;
+
+ if (context.module_init_method != null) {
+ module_init_fragment = new CCodeFragment ();
+ foreach (FormalParameter parameter in context.module_init_method.get_parameters ()) {
+ if (parameter.type_reference.data_type == type_module_type) {
+ in_plugin = true;
+ module_init_param_name = parameter.name;
+ break;
+ }
+ }
+ }
/* we're only interested in non-pkg source files */
var source_files = context.get_source_files ();
current_type_symbol = cl.symbol;
current_class = cl;
+ if (cl.is_static) {
+ 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 ()));
}
public override void visit_end_class (Class! cl) {
- add_get_property_function (cl);
- add_set_property_function (cl);
- add_class_init_function (cl);
-
- foreach (TypeReference base_type in cl.get_base_types ()) {
- if (base_type.data_type is Interface) {
- add_interface_init_function (cl, (Interface) base_type.data_type);
+ if (!cl.is_static) {
+ add_get_property_function (cl);
+ add_set_property_function (cl);
+ add_class_init_function (cl);
+
+ foreach (TypeReference base_type in cl.get_base_types ()) {
+ if (base_type.data_type is Interface) {
+ add_interface_init_function (cl, (Interface) base_type.data_type);
+ }
+ }
+
+ add_instance_init_function (cl);
+ if (memory_management && cl.get_fields () != null) {
+ add_dispose_function (cl);
+ }
+
+ var type_fun = new ClassRegisterFunction (cl);
+ type_fun.init_from_type (in_plugin);
+ header_type_member_declaration.append (type_fun.get_declaration ());
+ source_type_member_definition.append (type_fun.get_definition ());
+
+ if (in_plugin) {
+ // FIXME resolve potential dependency issues, i.e. base types have to be registered before derived types
+ var register_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_register_type".printf (cl.get_lower_case_cname (null))));
+ register_call.add_argument (new CCodeIdentifier (module_init_param_name));
+ module_init_fragment.append (new CCodeExpressionStatement (register_call));
}
}
-
- add_instance_init_function (cl);
- if (memory_management && cl.get_fields () != null) {
- add_dispose_function (cl);
- }
-
- var type_fun = new ClassRegisterFunction (cl);
- type_fun.init_from_type ();
- header_type_member_declaration.append (type_fun.get_declaration ());
- source_type_member_definition.append (type_fun);
current_type_symbol = null;
current_class = null;
var type_fun = new InterfaceRegisterFunction (iface);
type_fun.init_from_type ();
header_type_member_declaration.append (type_fun.get_declaration ());
- source_type_member_definition.append (type_fun);
+ source_type_member_definition.append (type_fun.get_definition ());
current_type_symbol = null;
}
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
cinit.append (cdecl);
}
+
+ if (context.module_init_method == m && in_plugin) {
+ // GTypeModule-based plug-in, register types
+ cinit.append (module_init_fragment);
+ }
}
}
var prereq = prereq_ref.data_type;
var func = new CCodeFunctionCall (new CCodeIdentifier ("g_type_interface_add_prerequisite"));
- func.add_argument (new CCodeIdentifier ("g_define_type_id"));
+ func.add_argument (new CCodeIdentifier ("%s_type_id".printf (interface_reference.get_lower_case_cname (null))));
func.add_argument (new CCodeIdentifier (prereq.get_type_id()));
frag.append (new CCodeExpressionStatement (func));
public override void visit_begin_method (Method! m) {
current_symbol = m.symbol;
current_return_type = m.return_type;
-
+
+ var init_attr = m.get_attribute ("ModuleInit");
+ if (init_attr != null) {
+ m.source_reference.file.context.module_init_method = m;
+ }
+
if (m.return_type.data_type != null) {
/* is null if it is void or a reference to a type parameter */
current_source_file.add_symbol_dependency (m.return_type.data_type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
/**
* C function to register a type at runtime.
*/
-public abstract class Vala.TypeRegisterFunction : CCodeFunction {
+public abstract class Vala.TypeRegisterFunction {
+ private CCodeFragment declaration_fragment = new CCodeFragment ();
+
+ private CCodeFragment definition_fragment = new CCodeFragment ();
+
/**
* Constructs the C function from the specified type.
*/
- public void init_from_type () {
- name = "%s_get_type".printf (get_type_declaration ().get_lower_case_cname (null));
- return_type = "GType";
+ public void init_from_type (bool plugin = false) {
+ string type_id_name = "%s_type_id".printf (get_type_declaration ().get_lower_case_cname (null));
var type_block = new CCodeBlock ();
var cdecl = new CCodeDeclaration ("GType");
- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_id", new CCodeConstant ("0")));
+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (type_id_name, new CCodeConstant ("0")));
cdecl.modifiers = CCodeModifiers.STATIC;
- type_block.add_statement (cdecl);
-
- var cond = new CCodeFunctionCall (new CCodeIdentifier ("G_UNLIKELY"));
- cond.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("g_define_type_id"), new CCodeConstant ("0")));
+ if (!plugin) {
+ type_block.add_statement (cdecl);
+ } else {
+ definition_fragment.append (cdecl);
+ }
+
+ CCodeFunction fun;
+ if (!plugin) {
+ fun = new CCodeFunction ("%s_get_type".printf (get_type_declaration ().get_lower_case_cname (null)), "GType");
+ } else {
+ fun = new CCodeFunction ("%s_register_type".printf (get_type_declaration ().get_lower_case_cname (null)), "GType");
+ fun.add_parameter (new CCodeFormalParameter ("module", "GTypeModule *"));
+
+ var get_fun = new CCodeFunction ("%s_get_type".printf (get_type_declaration ().get_lower_case_cname (null)), "GType");
+
+ declaration_fragment.append (get_fun.copy ());
+
+ get_fun.block = new CCodeBlock ();
+ get_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name)));
+
+ definition_fragment.append (get_fun);
+ }
+
var type_init = new CCodeBlock ();
var ctypedecl = new CCodeDeclaration ("const GTypeInfo");
ctypedecl.modifiers = CCodeModifiers.STATIC;
ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) NULL, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s }".printf (get_type_struct_name (), get_base_init_func_name (), get_class_init_func_name (), get_instance_struct_size (), get_instance_init_func_name ()))));
type_init.add_statement (ctypedecl);
- var reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_register_static"));
+ CCodeFunctionCall reg_call;
+ if (!plugin) {
+ reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_register_static"));
+ } else {
+ reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_module_register_type"));
+ reg_call.add_argument (new CCodeIdentifier ("module"));
+ }
reg_call.add_argument (new CCodeIdentifier (get_parent_type_name ()));
reg_call.add_argument (new CCodeConstant ("\"%s\"".printf (get_type_declaration ().get_cname ())));
reg_call.add_argument (new CCodeIdentifier ("&g_define_type_info"));
reg_call.add_argument (new CCodeConstant (get_type_flags ()));
- type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("g_define_type_id"), reg_call)));
+ type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call)));
type_init.add_statement (get_type_interface_init_statements ());
-
- var cif = new CCodeIfStatement (cond, type_init);
- type_block.add_statement (cif);
- type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("g_define_type_id")));
- block = type_block;
+ if (!plugin) {
+ var cond = new CCodeFunctionCall (new CCodeIdentifier ("G_UNLIKELY"));
+ cond.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier (type_id_name), new CCodeConstant ("0")));
+ var cif = new CCodeIfStatement (cond, type_init);
+ type_block.add_statement (cif);
+ } else {
+ type_block = type_init;
+ }
+
+ type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name)));
+
+ declaration_fragment.append (fun.copy ());
+
+ fun.block = type_block;
+
+ definition_fragment.append (fun);
}
/**
/**
* Returns the declaration for this type register function in C code.
*
- * @return C function declaration
+ * @return C function declaration fragment
+ */
+ public CCodeFragment! get_declaration () {
+ return declaration_fragment;
+ }
+
+ /**
+ * Returns the definition for this type register function in C code.
+ *
+ * @return C function definition fragment
*/
- public ref CCodeFunction! get_declaration () {
- return new CCodeFunction (name, return_type);
+ public CCodeFragment! get_definition () {
+ return definition_fragment;
}
}
/* glib-2.0.vala
*
- * Copyright (C) 2006 Jürg Billeter, Raffaele Sandrini
+ * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
public struct TypeClass {
}
-
+
+ public interface TypePlugin {
+ }
+
+ public class TypeModule : TypePlugin {
+ public bool use ();
+ public void unuse ();
+ public void set_name (string! name);
+ }
+
[ReferenceType ()]
public struct ParamSpec {
}