+2006-07-19 Jürg Billeter <j@bitron.ch>
+
+ * vala/valatypereference.vala: use more expressive property names, add
+ stricter () method
+ * vala/parser.y, vala/valasymbolbuilder.vala,
+ vala/valasymbolresolver.vala, vala/valasemanticanalyzer.vala,
+ vala/valamemorymanager.vala, vala/valacodegenerator.vala,
+ vala/valainterfacewriter.vala, vala/valasourcefile.vala,
+ vala/valacallback.vala, vala/valaclassregisterfunction.vala,
+ vala/valasignal.vala: adapt to changes in TypeReference
+ * vala/valasourcefile.vala: replace public fields by properties /
+ private fields
+ * vala/valacodecontext.vala: adapt to changes in SourceFile
+ * vala/valaparser.vala: correct handling of source files without header
+ comments
+ * vala/valasymbolbuilder.vala: don't generate code for VAPI files
+ * vala/valasemanticanalyzer.vala: report error respectively warning if
+ method return type misses ownership transfer
+ * vala/valainterfacewriter.vala: correct property declaration output
+ * vala/valaparser.vala, vala/valasourcefile.vala, vala/valaliteral.vala,
+ vala/valamemberaccessibility.vala, vala/valanamedargument.vala,
+ vala/valanamespacereference.vala, vala/valatypereference.vala: add
+ interface documentation, use implicit namespace specification
+
2006-07-18 Jürg Billeter <j@bitron.ch>
* vala/valasymbolresolver.vala: make sure that current_scope isn't null
ValaSourceReference *src = src(@2);
$$ = vala_type_reference_new_from_expression ($2, src);
g_object_unref (src);
- vala_type_reference_set_is_lvalue_ref ($$, TRUE);
+ vala_type_reference_set_takes_ownership ($$, TRUE);
if ($4) {
vala_type_reference_set_non_null ($$, TRUE);
}
: comment opt_attributes opt_access_modifier opt_modifiers type variable_declarator SEMICOLON
{
if (!vala_type_reference_get_is_weak ($5)) {
- vala_type_reference_set_is_lvalue_ref ($5, TRUE);
+ vala_type_reference_set_takes_ownership ($5, TRUE);
}
vala_type_reference_set_is_ref ($5, FALSE);
for (l = vala_type_reference_get_type_arguments ($5); l != NULL; l = l->next) {
ValaTypeReference *type_arg = VALA_TYPE_REFERENCE (l->data);
if (!vala_type_reference_get_is_weak (type_arg)) {
- vala_type_reference_set_is_ref (type_arg, TRUE);
+ vala_type_reference_set_takes_ownership (type_arg, TRUE);
}
}
{
GList *l;
+ if (vala_type_reference_get_is_ref ($5)) {
+ vala_type_reference_set_transfers_ownership ($5, TRUE);
+ }
+
ValaSourceReference *src = src_com(@6, $1);
$$ = vala_method_new ($6, $5, src);
g_object_unref (src);
: opt_attributes type IDENTIFIER
{
if (vala_type_reference_get_is_ref ($2) && vala_type_reference_get_is_out ($2)) {
- vala_type_reference_set_is_lvalue_ref ($2, TRUE);
+ vala_type_reference_set_takes_ownership ($2, TRUE);
vala_type_reference_set_is_ref ($2, FALSE);
}
| opt_attributes type IDENTIFIER ASSIGN expression
{
if (vala_type_reference_get_is_ref ($2) && vala_type_reference_get_is_out ($2)) {
- vala_type_reference_set_is_lvalue_ref ($2, TRUE);
+ vala_type_reference_set_takes_ownership ($2, TRUE);
vala_type_reference_set_is_ref ($2, FALSE);
}
: comment opt_attributes opt_access_modifier opt_modifiers type IDENTIFIER OPEN_BRACE get_accessor_declaration opt_set_accessor_declaration CLOSE_BRACE
{
if (!vala_type_reference_get_is_weak ($5)) {
- vala_type_reference_set_is_lvalue_ref ($5, TRUE);
+ vala_type_reference_set_takes_ownership ($5, TRUE);
}
GList *l;
for (l = vala_type_reference_get_type_arguments ($5); l != NULL; l = l->next) {
ValaTypeReference *type_arg = VALA_TYPE_REFERENCE (l->data);
if (!vala_type_reference_get_is_weak (type_arg)) {
- vala_type_reference_set_is_ref (type_arg, TRUE);
+ vala_type_reference_set_takes_ownership (type_arg, TRUE);
}
}
| comment opt_attributes opt_access_modifier opt_modifiers type IDENTIFIER OPEN_BRACE set_accessor_declaration CLOSE_BRACE
{
if (!vala_type_reference_get_is_weak ($5)) {
- vala_type_reference_set_is_lvalue_ref ($5, TRUE);
+ vala_type_reference_set_takes_ownership ($5, TRUE);
}
ValaSourceReference *src = src_com(@5, $1);
* @return true if the specified method is compatible to this callback
*/
public bool matches_method (Method! m) {
- if (m.return_type.type != return_type.type) {
+ if (!m.return_type.stricter (return_type)) {
return false;
}
}
var method_param = (FormalParameter) method_params_it.data;
- if (method_param.type_reference.type != param.type_reference.type) {
+ if (!param.type_reference.stricter (method_param.type_reference)) {
return false;
}
var frag = new CCodeFragment ();
foreach (TypeReference base_type in class_reference.get_base_types ()) {
- if (!(base_type.type is Interface)) {
+ if (!(base_type.data_type is Interface)) {
continue;
}
- var iface = (Interface) base_type.type;
+ var iface = (Interface) base_type.data_type;
var iface_info_name = "%s_info".printf (iface.get_lower_case_cname (null));
continue;
}
- foreach (SourceFile dep in file2.header_internal_dependencies) {
+ 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.header_internal_includes.append (file2.cycle.head.get_cheader_filename ());
+ file2.add_header_internal_include (file2.cycle.head.get_cheader_filename ());
}
} else {
/* we can just include the headers if they are not in a cycle or not in the same cycle as the current file */
- file2.header_internal_includes.append (dep.get_cheader_filename ());
+ file2.add_header_internal_include (dep.get_cheader_filename ());
}
}
}
}
private SourceFile find_cycle_head (SourceFile! file) {
- foreach (SourceFile dep in file.header_internal_full_dependencies) {
+ foreach (SourceFile dep in file.get_header_internal_full_dependencies ()) {
if (dep == file) {
/* ignore file-internal dependencies */
continue;
/* mark file as currently being visited */
file.mark = 1;
- foreach (SourceFile dep in file.header_internal_dependencies) {
+ foreach (SourceFile dep in file.get_header_internal_dependencies ()) {
if (file == dep) {
continue;
}
root_symbol = context.get_root ();
bool_type = new TypeReference ();
- bool_type.type = (DataType) root_symbol.lookup ("bool").node;
+ bool_type.data_type = (DataType) root_symbol.lookup ("bool").node;
string_type = new TypeReference ();
- string_type.type = (DataType) root_symbol.lookup ("string").node;
+ string_type.data_type = (DataType) root_symbol.lookup ("string").node;
/* we're only interested in non-pkg source files */
var source_files = context.get_source_files ();
used_includes.append ("glib.h");
used_includes.append (source_file.get_cheader_filename ());
- foreach (string filename1 in source_file.header_external_includes) {
+ foreach (string filename1 in source_file.get_header_external_includes ()) {
if (used_includes.find_custom (filename1, strcmp) == null) {
header_begin.append (new CCodeIncludeDirective (filename = filename1));
used_includes.append (filename1);
}
}
- foreach (string filename2 in source_file.header_internal_includes) {
+ foreach (string filename2 in source_file.get_header_internal_includes ()) {
if (used_includes.find_custom (filename2, strcmp) == null) {
header_begin.append (new CCodeIncludeDirective (filename = filename2));
used_includes.append (filename2);
}
}
- foreach (string filename3 in source_file.source_includes) {
+ foreach (string filename3 in source_file.get_source_includes ()) {
if (used_includes.find_custom (filename3, strcmp) == null) {
source_include_directives.append (new CCodeIncludeDirective (filename = filename3));
used_includes.append (filename3);
add_class_init_function (cl);
foreach (TypeReference base_type in cl.get_base_types ()) {
- if (base_type.type is Interface) {
- add_interface_init_function (cl, (Interface) base_type.type);
+ if (base_type.data_type is Interface) {
+ add_interface_init_function (cl, (Interface) base_type.data_type);
}
}
cspec.add_argument (prop.get_canonical_cconstant ());
cspec.add_argument (new CCodeConstant (name = "\"foo\""));
cspec.add_argument (new CCodeConstant (name = "\"bar\""));
- if (prop.type_reference.type is Class) {
+ if (prop.type_reference.data_type is Class) {
cspec.call = new CCodeIdentifier (name = "g_param_spec_object");
- cspec.add_argument (new CCodeIdentifier (name = prop.type_reference.type.get_upper_case_cname ("TYPE_")));
+ cspec.add_argument (new CCodeIdentifier (name = prop.type_reference.data_type.get_upper_case_cname ("TYPE_")));
} else if (prop.type_reference.type_name == "string") {
cspec.call = new CCodeIdentifier (name = "g_param_spec_string");
cspec.add_argument (new CCodeConstant (name = "NULL"));
} else if (prop.type_reference.type_name == "int"
- || prop.type_reference.type is Enum) {
+ || prop.type_reference.data_type is Enum) {
cspec.call = new CCodeIdentifier (name = "g_param_spec_int");
cspec.add_argument (new CCodeConstant (name = "G_MININT"));
cspec.add_argument (new CCodeConstant (name = "G_MAXINT"));
var params = sig.get_parameters ();
var params_len = params.length ();
- if (sig.return_type.type == null) {
+ if (sig.return_type.data_type == null) {
marshaller = "%s_VOID_".printf (marshaller);
csignew.add_argument (new CCodeConstant (name = "G_TYPE_NONE"));
} else {
- marshaller = "%s_%s_".printf (marshaller, sig.return_type.type.get_marshaller_type_name ());
- csignew.add_argument (new CCodeConstant (name = sig.return_type.type.get_type_id ()));
+ marshaller = "%s_%s_".printf (marshaller, sig.return_type.data_type.get_marshaller_type_name ());
+ csignew.add_argument (new CCodeConstant (name = sig.return_type.data_type.get_type_id ()));
}
csignew.add_argument (new CCodeConstant (name = "%d".printf (params_len)));
foreach (FormalParameter param in params) {
- marshaller = "%s_%s".printf (marshaller, param.type_reference.type.get_marshaller_type_name ());
- csignew.add_argument (new CCodeConstant (name = param.type_reference.type.get_type_id ()));
+ marshaller = "%s_%s".printf (marshaller, param.type_reference.data_type.get_marshaller_type_name ());
+ csignew.add_argument (new CCodeConstant (name = param.type_reference.data_type.get_type_id ()));
}
if (params_len == 0) {
var fields = cl.get_fields ();
foreach (Field f in fields) {
- if (f.instance && f.type_reference.is_lvalue_ref) {
+ if (f.instance && f.type_reference.takes_ownership) {
var cself = new CCodeIdentifier (name = "self");
CCodeExpression cstruct = cself;
if (f.access == MemberAccessibility.PRIVATE) {
var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name)));
ccall.add_argument (new CCodeIdentifier (name = "self"));
var csetcall = new CCodeFunctionCall ();
- if (prop.type_reference.type is Class) {
+ if (prop.type_reference.data_type is Class) {
csetcall.call = new CCodeIdentifier (name = "g_value_set_object");
} else if (prop.type_reference.type_name == "string") {
csetcall.call = new CCodeIdentifier (name = "g_value_set_string");
} else if (prop.type_reference.type_name == "int"
- || prop.type_reference.type is Enum) {
+ || prop.type_reference.data_type is Enum) {
csetcall.call = new CCodeIdentifier (name = "g_value_set_int");
} else if (prop.type_reference.type_name == "bool") {
csetcall.call = new CCodeIdentifier (name = "g_value_set_boolean");
var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name)));
ccall.add_argument (new CCodeIdentifier (name = "self"));
var cgetcall = new CCodeFunctionCall ();
- if (prop.type_reference.type is Class) {
+ if (prop.type_reference.data_type is Class) {
cgetcall.call = new CCodeIdentifier (name = "g_value_get_object");
} else if (prop.type_reference.type_name == "string") {
cgetcall.call = new CCodeIdentifier (name = "g_value_get_string");
} else if (prop.type_reference.type_name == "int"
- || prop.type_reference.type is Enum) {
+ || prop.type_reference.data_type is Enum) {
cgetcall.call = new CCodeIdentifier (name = "g_value_get_int");
} else if (prop.type_reference.type_name == "bool") {
cgetcall.call = new CCodeIdentifier (name = "g_value_get_boolean");
var t = (DataType) c.symbol.parent_symbol.node;
var cdecl = new CCodeDeclaration (type_name = c.type_reference.get_const_cname ());
var arr = "";
- if (c.type_reference.type is Array) {
+ if (c.type_reference.data_type is Array) {
arr = "[]";
}
cdecl.add_declarator (new CCodeVariableDeclarator (name = "%s%s".printf (c.get_cname (), arr), initializer = c.initializer.ccodenode));
}
private ref CCodeStatement create_method_type_check_statement (Method! m, DataType! t, bool non_null, string! var_name) {
- return create_type_check_statement (m, m.return_type.type, t, non_null, var_name);
+ return create_type_check_statement (m, m.return_type.data_type, t, non_null, var_name);
}
private ref CCodeStatement create_property_type_check_statement (Property! prop, bool getter, DataType! t, bool non_null, string! var_name) {
if (getter) {
- return create_type_check_statement (prop, prop.type_reference.type, t, non_null, var_name);
+ return create_type_check_statement (prop, prop.type_reference.data_type, t, non_null, var_name);
} else {
return create_type_check_statement (prop, null, t, non_null, var_name);
}
if (m.instance) {
var this_type = new TypeReference ();
- this_type.type = find_parent_type (m);
+ this_type.data_type = find_parent_type (m);
if (!m.overrides) {
instance_param = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
} else {
var base_type = new TypeReference ();
- base_type.type = (DataType) m.base_method.symbol.parent_symbol.node;
+ base_type.data_type = (DataType) m.base_method.symbol.parent_symbol.node;
instance_param = new CCodeFormalParameter (type_name = base_type.get_cname (), name = "base");
}
if (!m.instance_last) {
}
}
foreach (FormalParameter param in m.get_parameters ()) {
- var t = param.type_reference.type;
+ var t = param.type_reference.data_type;
if (t != null && t.is_reference_type () && !param.type_reference.is_out) {
var type_check = create_method_type_check_statement (m, t, param.type_reference.non_null, param.name);
if (type_check != null) {
var vfunc = new CCodeFunction (name = m.get_cname (), return_type = m.return_type.get_cname ());
var this_type = new TypeReference ();
- this_type.type = (DataType) m.symbol.parent_symbol.node;
+ this_type.data_type = (DataType) m.symbol.parent_symbol.node;
var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
vfunc.add_parameter (cparam);
function = new CCodeFunction (name = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name), return_type = "void");
}
var this_type = new TypeReference ();
- this_type.type = cl;
+ this_type.data_type = cl;
var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
function.add_parameter (cparam);
if (acc.writable || acc.construct_) {
if (memory_management) {
foreach (VariableDeclarator decl in local_vars) {
- if (decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
+ if (decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
cblock.add_statement (new CCodeExpressionStatement (expression = get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference)));
}
}
if (decl.initializer != null) {
rhs = (CCodeExpression) decl.initializer.ccodenode;
- if (decl.type_reference.type != null
- && decl.initializer.static_type.type != null
- && decl.type_reference.type.is_reference_type ()
- && decl.initializer.static_type.type != decl.type_reference.type) {
- rhs = new InstanceCast (type_reference = decl.type_reference.type, inner = rhs);
+ if (decl.type_reference.data_type != null
+ && decl.initializer.static_type.data_type != null
+ && decl.type_reference.data_type.is_reference_type ()
+ && decl.initializer.static_type.data_type != decl.type_reference.data_type) {
+ rhs = new InstanceCast (type_reference = decl.type_reference.data_type, inner = rhs);
}
- } else if (decl.type_reference.type != null && decl.type_reference.type.is_reference_type ()) {
+ } else if (decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type ()) {
rhs = new CCodeConstant (name = "NULL");
}
private ref VariableDeclarator get_temp_variable_declarator (TypeReference! type) {
var decl = new VariableDeclarator (name = "__temp%d".printf (next_temp_var_id));
decl.type_reference = type.copy ();
- decl.type_reference.is_ref = false;
+ decl.type_reference.reference_to_value_type = false;
decl.type_reference.is_out = false;
next_temp_var_id++;
var cisnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = cvar, right = new CCodeConstant (name = "NULL"));
string unref_function;
- if (type.type.is_reference_counting ()) {
- unref_function = type.type.get_unref_function ();
+ if (type.data_type.is_reference_counting ()) {
+ unref_function = type.data_type.get_unref_function ();
} else {
- unref_function = type.type.get_free_function ();
+ unref_function = type.data_type.get_free_function ();
}
- if (type.type is Array && ((Array)type.type).element_type.name == "string") {
+ if (type.data_type is Array && ((Array) type.data_type).element_type.name == "string") {
unref_function = "g_strfreev";
}
var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = unref_function));
bool is_class = false;
var type_args = type.get_type_arguments ();
foreach (TypeReference type_arg in type_args) {
- is_ref = type_arg.is_ref;
- is_class = type_arg.type is Class;
+ is_ref = type_arg.takes_ownership;
+ is_class = type_arg.data_type is Class;
}
if (is_ref) {
var vardecl = new CCodeVariableDeclarator (name = decl.name);
cdecl.add_declarator (vardecl);
- if (decl.type_reference.type != null && decl.type_reference.type.is_reference_type ()) {
+ if (decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type ()) {
vardecl.initializer = new CCodeConstant (name = "NULL");
}
public override void visit_end_foreach_statement (ForeachStatement! stmt) {
var cblock = new CCodeBlock ();
- if (stmt.collection.static_type.type is Array) {
+ if (stmt.collection.static_type.data_type is Array) {
var it_name = "%s_it".printf (stmt.variable_name);
var citdecl = new CCodeDeclaration (type_name = stmt.collection.static_type.get_cname ());
cfor.add_initializer (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = (CCodeExpression) stmt.collection.ccodenode));
cfor.add_iterator (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = new CCodeBinaryExpression (operator = CCodeBinaryOperator.PLUS, left = new CCodeIdentifier (name = it_name), right = new CCodeConstant (name = "1"))));
cblock.add_statement (cfor);
- } else if (stmt.collection.static_type.type.name == "List" ||
- stmt.collection.static_type.type.name == "SList") {
+ } else if (stmt.collection.static_type.data_type.name == "List" ||
+ stmt.collection.static_type.data_type.name == "SList") {
var it_name = "%s_it".printf (stmt.variable_name);
var citdecl = new CCodeDeclaration (type_name = stmt.collection.static_type.get_cname ());
var local_vars = b.get_local_variables ();
foreach (VariableDeclarator decl in local_vars) {
- if (decl.symbol.active && decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
+ if (decl.symbol.active && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
cfrag.append (new CCodeExpressionStatement (expression = get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference)));
}
}
var local_vars = b.get_local_variables ();
foreach (VariableDeclarator decl in local_vars) {
- if (decl.symbol.active && decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
+ if (decl.symbol.active && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
found = true;
ccomma.append_expression (get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference));
}
if (p.name == "this") {
expr.ccodenode = pub_inst;
} else {
- if (p.type_reference.is_out || p.type_reference.is_ref) {
+ if (p.type_reference.is_out || p.type_reference.reference_to_value_type) {
expr.ccodenode = new CCodeIdentifier (name = "*%s".printf (p.name));
} else {
expr.ccodenode = new CCodeIdentifier (name = p.name);
pub_inst = (CCodeExpression) expr.inner.ccodenode;
if (expr.inner.static_type != null) {
- base_type = expr.inner.static_type.type;
+ base_type = expr.inner.static_type.data_type;
}
}
if (expr.call.symbol_reference.node is VariableDeclarator) {
var decl = (VariableDeclarator) expr.call.symbol_reference.node;
- var cb = (Callback) decl.type_reference.type;
+ var cb = (Callback) decl.type_reference.data_type;
params = cb.get_parameters ();
} else if (expr.call.symbol_reference.node is FormalParameter) {
var param = (FormalParameter) expr.call.symbol_reference.node;
- var cb = (Callback) param.type_reference.type;
+ var cb = (Callback) param.type_reference.data_type;
params = cb.get_parameters ();
} else if (expr.call.symbol_reference.node is Method) {
m = (Method) expr.call.symbol_reference.node;
instance = (CCodeExpression) ma.inner.ccodenode;
/* reqiure casts if the type of the used instance is
* different than the type which declared the method */
- req_cast = base_method.symbol.parent_symbol.node != ma.inner.static_type.type;
+ req_cast = base_method.symbol.parent_symbol.node != ma.inner.static_type.data_type;
}
if (req_cast && ((DataType) m.symbol.parent_symbol.node).is_reference_type ()) {
if (params != null) {
var param = (FormalParameter) params.data;
if (!param.ellipsis
- && param.type_reference.type != null
- && param.type_reference.type.is_reference_type ()
- && arg.static_type.type != null
- && param.type_reference.type != arg.static_type.type) {
- var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = param.type_reference.type.get_upper_case_cname (null)));
+ && param.type_reference.data_type != null
+ && param.type_reference.data_type.is_reference_type ()
+ && arg.static_type.data_type != null
+ && param.type_reference.data_type != arg.static_type.data_type) {
+ var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = param.type_reference.data_type.get_upper_case_cname (null)));
ccall.add_argument (cexpr);
cexpr = ccall;
}
* if static type of expr is non-null
*/
- if (expr.static_type.type == null &&
+ if (expr.static_type.data_type == null &&
expr.static_type.type_parameter != null) {
expr.error = true;
Report.error (expr.source_reference, "Missing generics support for memory management");
}
string ref_function;
- if (expr.static_type.type.is_reference_counting ()) {
- ref_function = expr.static_type.type.get_ref_function ();
+ if (expr.static_type.data_type.is_reference_counting ()) {
+ ref_function = expr.static_type.data_type.get_ref_function ();
} else {
- ref_function = expr.static_type.type.get_dup_function ();
+ ref_function = expr.static_type.data_type.get_dup_function ();
}
var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = ref_function));
private void visit_expression (Expression! expr) {
if (expr.static_type != null &&
- expr.static_type.is_ref &&
+ expr.static_type.transfers_ownership &&
expr.static_type.floating_reference) {
/* constructor of GInitiallyUnowned subtype
* returns floating reference, sink it
}
public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
- if (expr.type_reference.type is Class) {
+ if (expr.type_reference.data_type is Class) {
var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_new"));
- ccall.add_argument (new CCodeConstant (name = expr.type_reference.get_upper_case_cname ("TYPE_")));
+ ccall.add_argument (new CCodeConstant (name = expr.type_reference.data_type.get_upper_case_cname ("TYPE_")));
foreach (NamedArgument arg in expr.named_argument_list) {
ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (arg.name)));
} else {
var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_new0"));
- ccall.add_argument (new CCodeConstant (name = expr.type_reference.type.get_cname ()));
+ ccall.add_argument (new CCodeConstant (name = expr.type_reference.data_type.get_cname ()));
ccall.add_argument (new CCodeConstant (name = "1"));
}
public override void visit_typeof_expression (TypeofExpression! expr) {
- expr.ccodenode = new CCodeIdentifier (name = expr.type_reference.type.get_type_id ());
+ expr.ccodenode = new CCodeIdentifier (name = expr.type_reference.data_type.get_type_id ());
}
public override void visit_unary_expression (UnaryExpression! expr) {
}
public override void visit_cast_expression (CastExpression! expr) {
- if (expr.type_reference.type is Struct || expr.type_reference.type is Enum || expr.type_reference.type is Flags) {
+ if (expr.type_reference.data_type is Struct || expr.type_reference.data_type is Enum || expr.type_reference.data_type is Flags) {
expr.ccodenode = expr.inner.ccodenode;
} else {
- expr.ccodenode = new InstanceCast (type_reference = expr.type_reference.type, inner = (CCodeExpression) expr.inner.ccodenode);
+ expr.ccodenode = new InstanceCast (type_reference = expr.type_reference.data_type, inner = (CCodeExpression) expr.inner.ccodenode);
}
visit_expression (expr);
}
public override void visit_type_check (TypeCheck! expr) {
- var ccheck = new CCodeFunctionCall (call = new CCodeIdentifier (name = expr.type_reference.type.get_upper_case_cname ("IS_")));
+ var ccheck = new CCodeFunctionCall (call = new CCodeIdentifier (name = expr.type_reference.data_type.get_upper_case_cname ("IS_")));
ccheck.add_argument ((CCodeExpression) expr.expression.ccodenode);
expr.ccodenode = ccheck;
}
instance = (CCodeExpression) ma.inner.ccodenode;
/* require casts if the type of the used instance is
* different than the type which declared the property */
- req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.type;
+ req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.data_type;
}
if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
if (prop.no_accessor_method) {
/* property name is second argument of g_object_set */
ccall.add_argument (prop.get_canonical_cconstant ());
- } else if (prop.type_reference.type != null
- && prop.type_reference.type.is_reference_type ()
- && a.right.static_type.type != null
- && prop.type_reference.type != a.right.static_type.type) {
+ } else if (prop.type_reference.data_type != null
+ && prop.type_reference.data_type.is_reference_type ()
+ && a.right.static_type.data_type != null
+ && prop.type_reference.data_type != a.right.static_type.data_type) {
/* cast is necessary */
- var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = prop.type_reference.type.get_upper_case_cname (null)));
+ var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = prop.type_reference.data_type.get_upper_case_cname (null)));
ccast.add_argument (cexpr);
cexpr = ccast;
}
*/
ref CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
- if (a.left.static_type.type != null
- && a.right.static_type.type != null
- && a.left.static_type.type.is_reference_type ()
- && a.right.static_type.type != a.left.static_type.type) {
- var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = a.left.static_type.type.get_upper_case_cname (null)));
+ if (a.left.static_type.data_type != null
+ && a.right.static_type.data_type != null
+ && a.left.static_type.data_type.is_reference_type ()
+ && a.right.static_type.data_type != a.left.static_type.data_type) {
+ var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = a.left.static_type.data_type.get_upper_case_cname (null)));
ccast.add_argument (rhs);
rhs = ccast;
}
- if (memory_management && a.left.static_type.is_lvalue_ref) {
+ if (memory_management && a.left.static_type.takes_ownership) {
/* unref old value */
var ccomma = new CCodeCommaExpression ();
} else {
first = false;
}
- write_string (base_type.type.symbol.get_full_name ());
+ write_string (base_type.data_type.symbol.get_full_name ());
}
}
write_begin_block ();
write_indent ();
write_string ("public ");
- if (f.type_reference.is_weak) {
+ if (!f.type_reference.takes_ownership) {
write_string ("weak ");
}
- write_string (f.type_reference.type.symbol.get_full_name ());
+ write_string (f.type_reference.data_type.symbol.get_full_name ());
var type_args = f.type_reference.get_type_arguments ();
if (type_args != null) {
write_string ("<");
foreach (TypeReference type_arg in type_args) {
- if (type_arg.is_weak) {
+ if (!type_arg.takes_ownership) {
write_string ("weak ");
}
- write_string (type_arg.type.symbol.get_full_name ());
+ write_string (type_arg.data_type.symbol.get_full_name ());
}
write_string (">");
}
write_string ("virtual ");
}
- var type = m.return_type.type;
+ var type = m.return_type.data_type;
if (type == null) {
write_string ("void");
} else {
- if (m.return_type.is_ref) {
+ if (m.return_type.transfers_ownership) {
write_string ("ref ");
}
- write_string (m.return_type.type.symbol.get_full_name ());
+ write_string (m.return_type.data_type.symbol.get_full_name ());
}
write_string (" ");
first = false;
}
- if (param.type_reference.is_ref) {
+ if (param.type_reference.reference_to_value_type ||
+ param.type_reference.takes_ownership) {
write_string ("ref ");
} else if (param.type_reference.is_out) {
write_string ("out ");
}
- write_string (param.type_reference.type.symbol.get_full_name ());
+ write_string (param.type_reference.data_type.symbol.get_full_name ());
var type_args = param.type_reference.get_type_arguments ();
if (type_args != null) {
write_string ("<");
foreach (TypeReference type_arg in type_args) {
- if (type_arg.is_ref) {
+ if (type_arg.takes_ownership) {
write_string ("ref ");
}
- write_string (type_arg.type.symbol.get_full_name ());
+ write_string (type_arg.data_type.symbol.get_full_name ());
}
write_string (">");
}
write_indent ();
write_string ("public ");
- if (prop.type_reference.is_weak) {
+ if (!prop.type_reference.takes_ownership) {
write_string ("weak ");
}
- write_string (prop.type_reference.type.symbol.get_full_name ());
+ write_string (prop.type_reference.data_type.symbol.get_full_name ());
var type_args = prop.type_reference.get_type_arguments ();
if (type_args != null) {
write_string ("<");
foreach (TypeReference type_arg in type_args) {
- if (type_arg.is_weak) {
+ if (!type_arg.takes_ownership) {
write_string ("weak ");
}
- write_string (type_arg.type.symbol.get_full_name ());
+ write_string (type_arg.data_type.symbol.get_full_name ());
}
write_string (">");
}
write_string (" ");
write_identifier (prop.name);
- write_string (" { get; set construct; }");
+ write_string (" {");
+ if (prop.get_accessor != null) {
+ write_string (" get;");
+ }
+ if (prop.set_accessor != null) {
+ if (prop.set_accessor.writable) {
+ write_string (" set");
+ }
+ if (prop.set_accessor.construct_) {
+ write_string (" construct");
+ }
+ write_string (";");
+ }
+ write_string (" }");
write_newline ();
}
using GLib;
-namespace Vala {
- public abstract class Literal : CodeNode {
- public TypeReference static_type { get; set; }
- }
+/**
+ * Base class for all literals in the source code.
+ */
+public abstract class Vala.Literal : CodeNode {
+ /**
+ * Specifies the type of this literal.
+ */
+ public TypeReference static_type { get; set; }
}
using GLib;
-namespace Vala {
- public enum MemberAccessibility {
- PRIVATE,
- INTERNAL,
- PUBLIC
- }
+public enum Vala.MemberAccessibility {
+ PRIVATE,
+ INTERNAL,
+ PUBLIC
}
private void visit_possibly_leaked_expression (Expression! expr) {
if (expr.static_type != null &&
- ((expr.static_type.type != null &&
- expr.static_type.type.is_reference_type ()) ||
+ ((expr.static_type.data_type != null &&
+ expr.static_type.data_type.is_reference_type ()) ||
expr.static_type.type_parameter != null) &&
- expr.static_type.is_ref) {
+ expr.static_type.transfers_ownership) {
/* mark reference as leaked */
expr.ref_leaked = true;
}
private void visit_possibly_missing_copy_expression (Expression! expr) {
if (expr.static_type != null &&
- ((expr.static_type.type != null &&
- expr.static_type.type.is_reference_type ()) ||
+ ((expr.static_type.data_type != null &&
+ expr.static_type.data_type.is_reference_type ()) ||
expr.static_type.type_parameter != null) &&
- !expr.static_type.is_ref) {
+ !expr.static_type.transfers_ownership) {
/* mark reference as missing */
expr.ref_missing = true;
}
public override void visit_field (Field! f) {
if (f.initializer != null) {
- if (f.type_reference.is_lvalue_ref) {
+ if (f.type_reference.takes_ownership) {
visit_possibly_missing_copy_expression (f.initializer);
} else {
visit_possibly_leaked_expression (f.initializer);
public override void visit_variable_declarator (VariableDeclarator! decl) {
if (decl.initializer != null) {
- if (decl.type_reference.is_lvalue_ref) {
+ if (decl.type_reference.takes_ownership) {
visit_possibly_missing_copy_expression (decl.initializer);
} else {
visit_possibly_leaked_expression (decl.initializer);
if (current_symbol.node is Method) {
var m = (Method) current_symbol.node;
- if (m.return_type.is_ref) {
+ if (m.return_type.transfers_ownership) {
visit_possibly_missing_copy_expression (stmt.return_expression);
} else {
visit_possibly_leaked_expression (stmt.return_expression);
var msym = expr.call.symbol_reference;
if (msym.node is VariableDeclarator) {
var decl = (VariableDeclarator) msym.node;
- var cb = (Callback) decl.type_reference.type;
+ var cb = (Callback) decl.type_reference.data_type;
params = cb.get_parameters ();
} else if (msym.node is FormalParameter) {
var param = (FormalParameter) msym.node;
- var cb = (Callback) param.type_reference.type;
+ var cb = (Callback) param.type_reference.data_type;
params = cb.get_parameters ();
} else if (msym.node is Method) {
var m = (Method) msym.node;
if (params != null) {
var param = (FormalParameter) params.data;
if (!param.ellipsis
- && ((param.type_reference.type != null
- && param.type_reference.type.is_reference_type ())
+ && ((param.type_reference.data_type != null
+ && param.type_reference.data_type.is_reference_type ())
|| param.type_reference.type_parameter != null)) {
- bool is_ref = param.type_reference.is_ref;
+ bool is_ref = param.type_reference.takes_ownership;
if (is_ref && param.type_reference.type_parameter != null) {
if (expr.call is MemberAccess) {
var instance_type = ((MemberAccess) expr.call).inner.static_type;
foreach (TypeReference type_arg in instance_type.get_type_arguments ()) {
/* generic method parameters may only be strong references if the type argument is strong, too */
- is_ref = type_arg.is_ref;
+ is_ref = type_arg.takes_ownership;
}
}
}
public override void visit_end_assignment (Assignment! a) {
if (a.left.symbol_reference.node is Signal) {
} else {
- if (a.left.static_type.is_lvalue_ref) {
+ if (a.left.static_type.takes_ownership) {
visit_possibly_missing_copy_expression (a.right);
} else {
visit_possibly_leaked_expression (a.right);
using GLib;
-namespace Vala {
- public class NamedArgument : CodeNode {
- public string name { get; construct; }
- public Expression argument { get; construct; }
-
- public static ref NamedArgument new (string name, Expression arg, SourceReference source) {
- return (new NamedArgument (name = name, argument = arg, source_reference = source));
- }
-
- public override void accept (CodeVisitor! visitor) {
- argument.accept (visitor);
-
- visitor.visit_named_argument (this);
- }
+/**
+ * Represents a named argument in the source code. A named argument may be used
+ * when creating objects and attributes where no parameter list exists.
+ */
+public class Vala.NamedArgument : CodeNode {
+ /**
+ * The name of a property.
+ */
+ public string! name { get; set construct; }
+
+ /**
+ * The expression the property should assign.
+ */
+ public Expression! argument { get; set construct; }
+
+ /**
+ * Creates a new named argument.
+ *
+ * @param name property name
+ * @param arg property value expression
+ * @param source reference to source code
+ * @return newly created named argument
+ */
+ public static ref NamedArgument! new (string! name, Expression! arg, SourceReference source) {
+ return (new NamedArgument (name = name, argument = arg, source_reference = source));
+ }
+
+ public override void accept (CodeVisitor! visitor) {
+ argument.accept (visitor);
+
+ visitor.visit_named_argument (this);
}
}
using GLib;
-namespace Vala {
- public class NamespaceReference : CodeNode {
- public string name { get; construct; }
- public weak Symbol namespace_symbol;
+/**
+ * A reference to a namespace symbol.
+ */
+public class Vala.NamespaceReference : CodeNode {
+ /**
+ * The name of the namespace this reference is referring to.
+ */
+ public string! name { get; set construct; }
+
+ /**
+ * The resolved symbol of the namespace this reference is referring to.
+ */
+ public weak Symbol namespace_symbol { get; set; }
- public static ref NamespaceReference new (string name, SourceReference source) {
- return (new NamespaceReference (name = name, source_reference = source));
- }
-
- public override void accept (CodeVisitor! visitor) {
- visitor.visit_namespace_reference (this);
- }
+ /**
+ * Creates a new namespace reference.
+ *
+ * @param name namespace name
+ * @param source reference to source code
+ * @return newly created namespace reference
+ */
+ public static ref NamespaceReference! new (string! name, SourceReference source) {
+ return (new NamespaceReference (name = name, source_reference = source));
+ }
+
+ public override void accept (CodeVisitor! visitor) {
+ visitor.visit_namespace_reference (this);
}
}
using GLib;
-namespace Vala {
- public class Parser : CodeVisitor {
- string comment;
- string _file_comment;
-
- public void parse (CodeContext! context) {
- context.accept (this);
+/**
+ * Code visitor parsing all Vala source files.
+ */
+public class Vala.Parser : CodeVisitor {
+ private string comment;
+ private string _file_comment;
+
+ /**
+ * Parse all source files in the specified code context and build a
+ * code tree.
+ *
+ * @param context a code context
+ */
+ public void parse (CodeContext! context) {
+ context.accept (this);
+ }
+
+ public override void visit_begin_source_file (SourceFile! source_file) {
+ parse_file (source_file);
+ source_file.comment = _file_comment;
+ }
+
+ public override void visit_end_source_file (SourceFile! source_file) {
+ _file_comment = null;
+ }
+
+ /**
+ * Adds the specified comment to the comment stack.
+ *
+ * @param comment_item a comment string
+ * @param file_comment true if file header comment, false otherwise
+ */
+ public void push_comment (string! comment_item, bool file_comment) {
+ if (comment == null) {
+ comment = comment_item;
+ } else {
+ comment = "%s\n%s".printf (comment, comment_item);
+ }
+ if (file_comment) {
+ _file_comment = comment;
+ comment = null;
}
+ }
- public override void visit_begin_source_file (SourceFile! source_file) {
- parse_file (source_file);
- source_file.comment = _file_comment;
+ /**
+ * Clears and returns the content of the comment stack.
+ *
+ * @return saved comment
+ */
+ public ref string pop_comment () {
+ if (comment == null) {
+ return null;
}
- public void push_comment (string! comment_item, bool file_comment) {
- if (comment == null) {
- comment = comment_item;
- } else {
- comment = "%s\n%s".printf (comment, comment_item);
- }
- if (file_comment) {
- _file_comment = comment;
- comment = null;
- }
- }
+ String result = String.new (comment);
+ comment = null;
- public ref string pop_comment () {
- if (comment == null) {
- return null;
- }
-
- String result = String.new (comment);
- comment = null;
-
- string index;
- while ((index = result.str.chr (-1, '\t')) != null) {
- result.erase (result.str.pointer_to_offset (index), 1);
- }
-
- return result.str;
+ string index;
+ while ((index = result.str.chr (-1, '\t')) != null) {
+ result.erase (result.str.pointer_to_offset (index), 1);
}
- [Import ()]
- public void parse_file (SourceFile! source_file);
+ return result.str;
}
+
+ [Import ()]
+ public void parse_file (SourceFile! source_file);
}
root_symbol = context.get_root ();
bool_type = new TypeReference ();
- bool_type.type = (DataType) root_symbol.lookup ("bool").node;
+ bool_type.data_type = (DataType) root_symbol.lookup ("bool").node;
string_type = new TypeReference ();
- string_type.type = (DataType) root_symbol.lookup ("string").node;
+ string_type.data_type = (DataType) root_symbol.lookup ("string").node;
pointer_type = (DataType) root_symbol.lookup ("pointer").node;
int_type = new TypeReference ();
- int_type.type = (DataType) root_symbol.lookup ("int").node;
+ int_type.data_type = (DataType) root_symbol.lookup ("int").node;
var glib_ns = root_symbol.lookup ("GLib");
public override void visit_field (Field! f) {
if (f.access == MemberAccessibility.PUBLIC) {
- if (f.type_reference.type != null) {
+ if (f.type_reference.data_type != null) {
/* is null if it references a type parameter */
- current_source_file.add_symbol_dependency (f.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+ current_source_file.add_symbol_dependency (f.type_reference.data_type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
}
} else {
- if (f.type_reference.type != null) {
+ if (f.type_reference.data_type != null) {
/* is null if it references a type parameter */
- current_source_file.add_symbol_dependency (f.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ current_source_file.add_symbol_dependency (f.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
}
}
}
current_symbol = m.symbol;
current_return_type = m.return_type;
- if (m.return_type.type != null) {
+ 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.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+ current_source_file.add_symbol_dependency (m.return_type.data_type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
}
}
* by one of the base types
*/
foreach (TypeReference type in cl.get_base_types ()) {
- if (type.type is Interface) {
- var iface = (Interface) type.type;
+ if (type.data_type is Interface) {
+ var iface = (Interface) type.data_type;
var sym = iface.symbol.lookup (m.name);
if (sym != null && sym.node is Method) {
var base_method = (Method) sym.node;
public override void visit_formal_parameter (FormalParameter! p) {
if (!p.ellipsis) {
- if (p.type_reference.type != null) {
+ if (p.type_reference.data_type != null) {
/* is null if it references a type parameter */
- current_source_file.add_symbol_dependency (p.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
- current_source_file.add_symbol_dependency (p.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ current_source_file.add_symbol_dependency (p.type_reference.data_type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+ current_source_file.add_symbol_dependency (p.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
}
}
}
public override void visit_end_property (Property! prop) {
- if (prop.type_reference.type != null) {
+ if (prop.type_reference.data_type != null) {
/* is null if it references a type parameter */
- current_source_file.add_symbol_dependency (prop.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
- current_source_file.add_symbol_dependency (prop.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ current_source_file.add_symbol_dependency (prop.type_reference.data_type.symbol, SourceFileDependencyType.HEADER_SHALLOW);
+ current_source_file.add_symbol_dependency (prop.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
}
}
}
decl.type_reference = decl.initializer.static_type.copy ();
- decl.type_reference.is_lvalue_ref = decl.type_reference.is_ref;
- decl.type_reference.is_ref = false;
+ decl.type_reference.takes_ownership = decl.type_reference.transfers_ownership;
+ decl.type_reference.transfers_ownership = false;
}
if (decl.initializer != null) {
}
if (decl.initializer.symbol_reference.node is Method &&
- decl.type_reference.type is Callback) {
+ decl.type_reference.data_type is Callback) {
var m = (Method) decl.initializer.symbol_reference.node;
- var cb = (Callback) decl.type_reference.type;
+ var cb = (Callback) decl.type_reference.data_type;
/* check whether method matches callback type */
if (!cb.matches_method (m)) {
}
if (memory_management) {
- if (decl.initializer.static_type.is_ref) {
+ if (decl.initializer.static_type.transfers_ownership) {
/* rhs transfers ownership of the expression */
- if (!decl.type_reference.is_lvalue_ref) {
+ if (!decl.type_reference.takes_ownership) {
/* lhs doesn't own the value
* promote lhs type */
- decl.type_reference.is_lvalue_ref = true;
+ decl.type_reference.takes_ownership = true;
}
}
}
}
- if (decl.type_reference.type != null) {
- current_source_file.add_symbol_dependency (decl.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ if (decl.type_reference.data_type != null) {
+ current_source_file.add_symbol_dependency (decl.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
}
decl.symbol = new Symbol (node = decl);
public override void visit_expression_statement (ExpressionStatement! stmt) {
if (stmt.expression.static_type != null &&
- stmt.expression.static_type.is_ref) {
+ stmt.expression.static_type.transfers_ownership) {
Report.warning (stmt.source_reference, "Short-living reference");
return;
}
}
public override void visit_if_statement (IfStatement! stmt) {
- if (stmt.condition.static_type.type != bool_type.type) {
+ if (stmt.condition.static_type.data_type != bool_type.data_type) {
stmt.error = true;
Report.error (stmt.condition.source_reference, "Condition must be boolean");
return;
}
public override void visit_while_statement (WhileStatement! stmt) {
- if (stmt.condition.static_type.type != bool_type.type) {
+ if (stmt.condition.static_type.data_type != bool_type.data_type) {
stmt.error = true;
Report.error (stmt.condition.source_reference, "Condition must be boolean");
return;
}
public override void visit_for_statement (ForStatement! stmt) {
- if (stmt.condition.static_type.type != bool_type.type) {
+ if (stmt.condition.static_type.data_type != bool_type.data_type) {
stmt.error = true;
Report.error (stmt.condition.source_reference, "Condition must be boolean");
return;
}
public override void visit_begin_foreach_statement (ForeachStatement! stmt) {
- if (stmt.type_reference.type != null) {
- current_source_file.add_symbol_dependency (stmt.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ if (stmt.type_reference.data_type != null) {
+ current_source_file.add_symbol_dependency (stmt.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
}
stmt.variable_declarator = new VariableDeclarator (name = stmt.variable_name);
return;
}
- if (stmt.return_expression == null && current_return_type.type != null) {
+ if (stmt.return_expression == null && current_return_type.data_type != null) {
Report.error (stmt.source_reference, "Return with value in void function");
return;
}
- if (stmt.return_expression != null && current_return_type.type == null) {
+ if (stmt.return_expression != null && current_return_type.data_type == null) {
Report.error (stmt.source_reference, "Return without value in non-void function");
return;
}
return;
}
+ if (stmt.return_expression != null &&
+ stmt.return_expression.static_type.transfers_ownership &&
+ !current_return_type.transfers_ownership) {
+ stmt.error = true;
+ Report.error (stmt.source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership");
+ return;
+ }
+
+ if (stmt.return_expression != null &&
+ stmt.return_expression.symbol_reference != null &&
+ stmt.return_expression.symbol_reference.node is VariableDeclarator &&
+ stmt.return_expression.static_type.takes_ownership &&
+ !current_return_type.transfers_ownership) {
+ Report.warning (stmt.source_reference, "Local variable with strong reference used as return value and method return type hasn't been declared to transfer ownership");
+ }
}
public override void visit_boolean_literal (BooleanLiteral! expr) {
public override void visit_character_literal (CharacterLiteral! expr) {
expr.static_type = new TypeReference ();
- expr.static_type.type = (DataType) root_symbol.lookup ("char").node;
+ expr.static_type.data_type = (DataType) root_symbol.lookup ("char").node;
}
public override void visit_integer_literal (IntegerLiteral! expr) {
expr.static_type = new TypeReference ();
- expr.static_type.type = (DataType) root_symbol.lookup ("int").node;
+ expr.static_type.data_type = (DataType) root_symbol.lookup ("int").node;
}
public override void visit_real_literal (RealLiteral! expr) {
expr.static_type = new TypeReference ();
- expr.static_type.type = (DataType) root_symbol.lookup ("double").node;
+ expr.static_type.data_type = (DataType) root_symbol.lookup ("double").node;
}
public override void visit_string_literal (StringLiteral! expr) {
} else if (node is Property) {
var prop = (Property) node;
var type = prop.type_reference.copy ();
- type.is_lvalue_ref = false;
+ type.takes_ownership = false;
return type;
} else if (node is FormalParameter) {
var p = (FormalParameter) node;
return decl.type_reference;
} else if (node is EnumValue) {
var type = new TypeReference ();
- type.type = (DataType) node.symbol.parent_symbol.node;
+ type.data_type = (DataType) node.symbol.parent_symbol.node;
return type;
}
return null;
}
if (expr.symbol_reference == null && expr.inner.static_type != null) {
- base_symbol = expr.inner.static_type.type.symbol;
+ base_symbol = expr.inner.static_type.data_type.symbol;
expr.symbol_reference = symbol_lookup_inherited (base_symbol, expr.member_name);
}
}
private bool is_type_compatible (TypeReference! expression_type, TypeReference! expected_type) {
/* only null is compatible to null */
- if (expected_type.type == null && expected_type.type_parameter == null) {
- return (expression_type.type == null && expected_type.type_parameter == null);
+ if (expected_type.data_type == null && expected_type.type_parameter == null) {
+ return (expression_type.data_type == null && expected_type.type_parameter == null);
}
/* null can be casted to any reference or array type */
- if (expression_type.type == null &&
+ if (expression_type.data_type == null &&
(expected_type.type_parameter != null ||
- expected_type.type.is_reference_type () ||
- expected_type.is_ref ||
- expected_type.type is Array ||
- expected_type.type is Callback ||
- expected_type.type == pointer_type)) {
+ expected_type.data_type.is_reference_type () ||
+ expected_type.reference_to_value_type ||
+ expected_type.data_type is Array ||
+ expected_type.data_type is Callback ||
+ expected_type.data_type == pointer_type)) {
return true;
}
return true;
}
- if (expression_type.type is Array != expected_type.type is Array) {
+ if (expression_type.data_type is Array != expected_type.data_type is Array) {
return false;
}
- if (expression_type.type == expected_type.type) {
+ if (expression_type.data_type == expected_type.data_type) {
return true;
}
/* int may be implicitly casted to long */
- if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("long").node) {
+ if (expression_type.data_type == root_symbol.lookup ("int").node && expected_type.data_type == root_symbol.lookup ("long").node) {
return true;
}
/* int may be implicitly casted to ulong */
- if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("ulong").node) {
+ if (expression_type.data_type == root_symbol.lookup ("int").node && expected_type.data_type == root_symbol.lookup ("ulong").node) {
return true;
}
/* uint may be implicitly casted to long */
- if (expression_type.type == root_symbol.lookup ("uint").node && expected_type.type == root_symbol.lookup ("long").node) {
+ if (expression_type.data_type == root_symbol.lookup ("uint").node && expected_type.data_type == root_symbol.lookup ("long").node) {
return true;
}
/* uint may be implicitly casted to ulong */
- if (expression_type.type == root_symbol.lookup ("uint").node && expected_type.type == root_symbol.lookup ("ulong").node) {
+ if (expression_type.data_type == root_symbol.lookup ("uint").node && expected_type.data_type == root_symbol.lookup ("ulong").node) {
return true;
}
/* int may be implicitly casted to uint */
- if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("uint").node) {
+ if (expression_type.data_type == root_symbol.lookup ("int").node && expected_type.data_type == root_symbol.lookup ("uint").node) {
return true;
}
/* uint may be implicitly casted to int */
- if (expression_type.type == root_symbol.lookup ("uint").node && expected_type.type == root_symbol.lookup ("int").node) {
+ if (expression_type.data_type == root_symbol.lookup ("uint").node && expected_type.data_type == root_symbol.lookup ("int").node) {
return true;
}
/* long may be implicitly casted to ulong */
- if (expression_type.type == root_symbol.lookup ("long").node && expected_type.type == root_symbol.lookup ("ulong").node) {
+ if (expression_type.data_type == root_symbol.lookup ("long").node && expected_type.data_type == root_symbol.lookup ("ulong").node) {
return true;
}
/* ulong may be implicitly casted to long */
- if (expression_type.type == root_symbol.lookup ("ulong").node && expected_type.type == root_symbol.lookup ("long").node) {
+ if (expression_type.data_type == root_symbol.lookup ("ulong").node && expected_type.data_type == root_symbol.lookup ("long").node) {
return true;
}
/* int may be implicitly casted to double */
- if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("double").node) {
+ if (expression_type.data_type == root_symbol.lookup ("int").node && expected_type.data_type == root_symbol.lookup ("double").node) {
return true;
}
/* char may be implicitly casted to unichar */
- if (expression_type.type == root_symbol.lookup ("char").node && expected_type.type == root_symbol.lookup ("unichar").node) {
+ if (expression_type.data_type == root_symbol.lookup ("char").node && expected_type.data_type == root_symbol.lookup ("unichar").node) {
return true;
}
/* non-class types must match exactly */
- if (!(expression_type.type is Class)) {
+ if (!(expression_type.data_type is Class)) {
return false;
}
- var cl = (Class) expression_type.type;
+ var cl = (Class) expression_type.data_type;
var base_class = cl.base_class;
for (; base_class != null; base_class = base_class.base_class) {
- if (base_class == expected_type.type) {
+ if (base_class == expected_type.data_type) {
return true;
}
}
if (msym.node is VariableDeclarator) {
var decl = (VariableDeclarator) msym.node;
- if (decl.type_reference.type is Callback) {
- var cb = (Callback) decl.type_reference.type;
+ if (decl.type_reference.data_type is Callback) {
+ var cb = (Callback) decl.type_reference.data_type;
params = cb.get_parameters ();
} else {
expr.error = true;
}
} else if (msym.node is FormalParameter) {
var param = (FormalParameter) msym.node;
- if (param.type_reference.type is Callback) {
- var cb = (Callback) param.type_reference.type;
+ if (param.type_reference.data_type is Callback) {
+ var cb = (Callback) param.type_reference.data_type;
params = cb.get_parameters ();
} else {
expr.error = true;
if (msym.node is VariableDeclarator) {
var decl = (VariableDeclarator) msym.node;
- var cb = (Callback) decl.type_reference.type;
+ var cb = (Callback) decl.type_reference.data_type;
ret_type = cb.return_type;
params = cb.get_parameters ();
} else if (msym.node is FormalParameter) {
var param = (FormalParameter) msym.node;
- var cb = (Callback) param.type_reference.type;
+ var cb = (Callback) param.type_reference.data_type;
ret_type = cb.return_type;
params = cb.get_parameters ();
} else if (msym.node is Method) {
}
/* header file necessary if we need to cast argument */
- if (param.type_reference.type != null) {
- current_source_file.add_symbol_dependency (param.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ if (param.type_reference.data_type != null) {
+ current_source_file.add_symbol_dependency (param.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
}
if (arg_it == null) {
}
/* assign a static_type when possible */
- if (expr.container.static_type.type is Array) {
+ if (expr.container.static_type.data_type is Array) {
expr.static_type = new TypeReference ();
- expr.static_type.type = ((Array)expr.container.static_type.type).element_type;
+ expr.static_type.data_type = ((Array)expr.container.static_type.data_type).element_type;
} else {
expr.error = true;
Report.error (expr.source_reference, "The expression `%s' does not denote an Array".printf (expr.container.static_type.to_string ()));
}
/* check if the index is of type integer */
- if (expr.index.static_type.type != int_type.type) {
+ if (expr.index.static_type.data_type != int_type.data_type) {
expr.error = true;
Report.error (expr.source_reference, "The expression `%s' does not denote an `int' which is needed for element access".printf (expr.index.static_type.to_string ()));
}
}
public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
- if (expr.type_reference.type == null) {
+ if (expr.type_reference.data_type == null) {
/* if type resolving didn't succeed, skip this check */
return;
}
- if (!expr.type_reference.type.is_reference_type ()) {
+ if (!expr.type_reference.data_type.is_reference_type ()) {
expr.error = true;
Report.error (expr.source_reference, "Can't create instance of value type `%s'".printf (expr.type_reference.to_string ()));
return;
}
- current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ current_source_file.add_symbol_dependency (expr.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
expr.static_type = expr.type_reference.copy ();
- expr.static_type.is_ref = true;
+ expr.static_type.transfers_ownership = true;
- if (expr.type_reference.type is Class) {
- var cl = (Class) expr.type_reference.type;
+ if (expr.type_reference.data_type is Class) {
+ var cl = (Class) expr.type_reference.data_type;
if (cl.is_abstract) {
expr.static_type = null;
}
public override void visit_cast_expression (CastExpression! expr) {
- if (expr.type_reference.type == null) {
+ if (expr.type_reference.data_type == null) {
/* if type resolving didn't succeed, skip this check */
return;
}
- current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ current_source_file.add_symbol_dependency (expr.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
expr.static_type = expr.type_reference;
}
return;
}
- if (expr.left.static_type.type == string_type.type
+ if (expr.left.static_type.data_type == string_type.data_type
&& expr.operator == BinaryOperator.PLUS) {
- if (expr.right.static_type.type != string_type.type) {
+ if (expr.right.static_type.data_type != string_type.data_type) {
Report.error (expr.source_reference, "Operands must be strings");
}
|| expr.operator == BinaryOperator.GREATER_THAN
|| expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL
|| expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
- if (expr.left.static_type.type == string_type.type
- && expr.right.static_type.type == string_type.type) {
+ if (expr.left.static_type.data_type == string_type.data_type
+ && expr.right.static_type.data_type == string_type.data_type) {
/* string comparison: convert to a.collate (b) OP 0 */
var cmp_call = new InvocationExpression (call = new MemberAccess (inner = expr.left, member_name = "collate"));
return;
}
- if (expr.left.static_type.type == string_type.type
- && expr.right.static_type.type == string_type.type) {
+ if (expr.left.static_type.data_type == string_type.data_type
+ && expr.right.static_type.data_type == string_type.data_type) {
/* string comparison: convert to a.collate (b) OP 0 */
var cmp_call = new InvocationExpression (call = new MemberAccess (inner = expr.left, member_name = "collate"));
expr.static_type = expr.left.static_type;
} else if (expr.operator == BinaryOperator.AND
|| expr.operator == BinaryOperator.OR) {
- if (expr.left.static_type.type != bool_type.type || expr.right.static_type.type != bool_type.type) {
+ if (expr.left.static_type.data_type != bool_type.data_type || expr.right.static_type.data_type != bool_type.data_type) {
Report.error (expr.source_reference, "Operands must be boolean");
}
}
public override void visit_type_check (TypeCheck! expr) {
- if (expr.type_reference.type == null) {
+ if (expr.type_reference.data_type == null) {
/* if type resolving didn't succeed, skip this check */
return;
}
- current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
+ current_source_file.add_symbol_dependency (expr.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
expr.static_type = bool_type;
}
public override void visit_conditional_expression (ConditionalExpression! expr) {
- if (expr.condition.static_type.type != bool_type.type) {
+ if (expr.condition.static_type.data_type != bool_type.data_type) {
expr.error = true;
Report.error (expr.condition.source_reference, "Condition must be boolean");
return;
}
public override void visit_begin_lambda_expression (LambdaExpression! l) {
- if (l.expected_type == null || !(l.expected_type.type is Callback)) {
+ if (l.expected_type == null || !(l.expected_type.data_type is Callback)) {
l.error = true;
Report.error (l.source_reference, "lambda expression not allowed in this context");
return;
var current_method = find_current_method ();
- var cb = (Callback) l.expected_type.type;
+ var cb = (Callback) l.expected_type.data_type;
l.method = new Method (name = get_lambda_name (), return_type = cb.return_type);
l.method.instance = cb.instance && current_method.instance;
l.method.symbol = new Symbol (node = l.method);
block.symbol = new Symbol (node = block);
block.symbol.parent_symbol = l.method.symbol;
- if (l.method.return_type.type != null) {
+ if (l.method.return_type.data_type != null) {
block.add_statement (new ReturnStatement (return_expression = l.expression_body));
} else {
block.add_statement (new ExpressionStatement (expression = l.expression_body));
var sig = (Signal) ma.symbol_reference.node;
a.right.expected_type = new TypeReference ();
- a.right.expected_type.type = sig.get_callback ();
+ a.right.expected_type.data_type = sig.get_callback ();
}
}
var right_ma = (MemberAccess) a.right;
if (right_ma.symbol_reference.node is Method &&
- decl.type_reference.type is Callback) {
+ decl.type_reference.data_type is Callback) {
var m = (Method) right_ma.symbol_reference.node;
- var cb = (Callback) decl.type_reference.type;
+ var cb = (Callback) decl.type_reference.data_type;
/* check whether method matches callback type */
if (!cb.matches_method (m)) {
var right_ma = (MemberAccess) a.right;
if (right_ma.symbol_reference.node is Method &&
- f.type_reference.type is Callback) {
+ f.type_reference.data_type is Callback) {
var m = (Method) right_ma.symbol_reference.node;
- var cb = (Callback) f.type_reference.type;
+ var cb = (Callback) f.type_reference.data_type;
/* check whether method matches callback type */
if (!cb.matches_method (m)) {
}
if (memory_management) {
- if (a.right.static_type.is_ref) {
+ if (a.right.static_type.transfers_ownership) {
/* rhs transfers ownership of the expression */
- if (!a.left.static_type.is_lvalue_ref) {
+ if (!a.left.static_type.takes_ownership) {
/* lhs doesn't own the value
* promote lhs type if it is a local variable
* error if it's not a local variable */
Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
}
- a.left.static_type.is_lvalue_ref = true;
+ a.left.static_type.takes_ownership = true;
}
- } else if (a.left.static_type.is_lvalue_ref) {
+ } else if (a.left.static_type.takes_ownership) {
/* lhs wants to own the value
* rhs doesn't transfer the ownership
* code generator needs to add reference
var sender_param = new FormalParameter (name = "sender");
sender_param.type_reference = new TypeReference ();
- sender_param.type_reference.type = (DataType) symbol.parent_symbol.node;
+ sender_param.type_reference.data_type = (DataType) symbol.parent_symbol.node;
generated_callback.add_parameter (sender_param);
foreach (FormalParameter! param in parameters) {
using GLib;
-namespace Vala {
- public class SourceFile {
- public string filename { get; construct; }
- public string comment;
- public bool pkg { get; construct; }
-
- List<NamespaceReference> using_directives;
+/**
+ * Represents a Vala source or VAPI package file.
+ */
+public class Vala.SourceFile {
+ /**
+ * The name of this source file.
+ */
+ public string! filename { get; set construct; }
+
+ /**
+ * The header comment of this source file.
+ */
+ public string comment { get; set; }
+
+ /**
+ * Specifies whether this file is a VAPI package file.
+ */
+ public bool pkg { 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; }
+
+ private List<NamespaceReference> using_directives;
- Namespace global_namespace;
- List<Namespace> namespaces;
-
- private void init () {
- global_namespace = new Namespace (source_reference = new SourceReference (file = this));
- }
-
- public void add_using_directive (NamespaceReference ns) {
- using_directives.append (ns);
- }
-
- public List<NamespaceReference> get_using_directives () {
- return using_directives;
- }
-
- public void add_namespace (Namespace ns) {
- namespaces.append (ns);
- }
-
- public Namespace get_global_namespace () {
- return global_namespace;
- }
-
- public ref List<Namespace> get_namespaces () {
- return namespaces.copy ();
- }
-
- public void accept (CodeVisitor visitor) {
- visitor.visit_begin_source_file (this);
+ private Namespace global_namespace;
+ private List<Namespace> namespaces;
+
+ private string cheader_filename = null;
+
+ private string csource_filename = null;
+
+ private List<weak string> header_external_includes;
+ private List<weak string> header_internal_includes;
+ private List<weak string> source_includes;
+
+ private List<weak SourceFile> header_internal_full_dependencies;
+ private List<weak SourceFile> header_internal_dependencies;
+
+ SourceFile () {
+ global_namespace = new Namespace (source_reference = new SourceReference (file = this));
+ }
+
+ /**
+ * Adds a new using directive with the specified namespace.
+ *
+ * @param ns reference to namespace
+ */
+ public void add_using_directive (NamespaceReference! ns) {
+ using_directives.append (ns);
+ }
+
+ /**
+ * Returns a copy of the list of using directives.
+ *
+ * @return using directive list
+ */
+ public ref List<NamespaceReference> get_using_directives () {
+ return using_directives.copy ();
+ }
+
+ /**
+ * Adds the specified namespace to this source file.
+ *
+ * @param ns a namespace
+ */
+ public void add_namespace (Namespace! ns) {
+ namespaces.append (ns);
+ }
- foreach (NamespaceReference ns_ref in using_directives) {
- ns_ref.accept (visitor);
- }
-
- global_namespace.accept (visitor);
-
- foreach (Namespace ns in namespaces) {
- ns.accept (visitor);
- }
+ /**
+ * Returns the implicitly declared root namespace of this source file.
+ *
+ * @return root namespace
+ */
+ public Namespace! get_global_namespace () {
+ return global_namespace;
+ }
+
+ /**
+ * Returns a copy of the list of namespaces.
+ *
+ * @return namespace list
+ */
+ public ref List<Namespace> get_namespaces () {
+ return namespaces.copy ();
+ }
+
+ /**
+ * Visits this source file and all children with the specified
+ * CodeVisitor.
+ *
+ * @param visitor the visitor to be called while traversing
+ */
+ public void accept (CodeVisitor! visitor) {
+ visitor.visit_begin_source_file (this);
- visitor.visit_end_source_file (this);
+ foreach (NamespaceReference ns_ref in using_directives) {
+ ns_ref.accept (visitor);
}
- string cheader_filename = null;
+ global_namespace.accept (visitor);
- public string get_cheader_filename () {
- if (cheader_filename == null) {
- var basename = filename.ndup ((uint) (filename.len () - ".vala".len ()));
- cheader_filename = "%s.h".printf (basename);
- }
- return cheader_filename;
+ foreach (Namespace ns in namespaces) {
+ ns.accept (visitor);
}
-
- string csource_filename = null;
-
- public string get_csource_filename () {
- if (csource_filename == null) {
- var basename = filename.ndup ((uint) (filename.len () - ".vala".len ()));
- csource_filename = "%s.c".printf (basename);
- }
- return csource_filename;
+
+ visitor.visit_end_source_file (this);
+ }
+
+ /**
+ * Returns the filename to use when generating C header files.
+ *
+ * @return generated C header filename
+ */
+ public string! get_cheader_filename () {
+ if (cheader_filename == null) {
+ var basename = filename.ndup ((uint) (filename.len () - ".vala".len ()));
+ cheader_filename = "%s.h".printf (basename);
}
-
- public List<weak string> header_external_includes;
- public List<weak string> header_internal_includes;
- public List<weak string> source_includes;
-
- public List<weak SourceFile> header_internal_full_dependencies;
- public List<weak SourceFile> header_internal_dependencies;
- public SourceFileCycle cycle; // null = not in a cycle; if not null, don't write typedefs
- public bool is_cycle_head; // if true, write typedefs for all types in the cycle
- public int mark; // used for cycle detection, 0 = white (not yet visited), 1 = gray (currently visiting), 2 = black (already visited)
+ return cheader_filename;
+ }
+
+ /**
+ * Returns the filename to use when generating C source files.
+ *
+ * @return generated C source filename
+ */
+ public string! get_csource_filename () {
+ if (csource_filename == null) {
+ var basename = filename.ndup ((uint) (filename.len () - ".vala".len ()));
+ csource_filename = "%s.c".printf (basename);
+ }
+ return csource_filename;
+ }
- public void add_symbol_dependency (Symbol sym, SourceFileDependencyType dep_type) {
- DataType t;
-
- if (sym.node is DataType) {
- t = (DataType) sym.node;
- } else if (sym.node is Method || sym.node is Field) {
- if (sym.parent_symbol.node is DataType) {
- t = (DataType) sym.parent_symbol.node;
- } else {
- return;
- }
- } else if (sym.node is Property) {
+ /**
+ * Adds the specified symbol to the list of symbols code in this source
+ * file depends on.
+ *
+ * @param sym a symbol
+ * @param dep_type type of dependency
+ */
+ public void add_symbol_dependency (Symbol! sym, SourceFileDependencyType dep_type) {
+ DataType t;
+
+ if (sym.node is DataType) {
+ t = (DataType) sym.node;
+ } else if (sym.node is Method || sym.node is Field) {
+ if (sym.parent_symbol.node is DataType) {
t = (DataType) sym.parent_symbol.node;
- } else if (sym.node is FormalParameter) {
- var fp = (FormalParameter) sym.node;
- t = fp.type_reference.type;
- if (t == null) {
- /* generic type parameter */
- return;
- }
} else {
return;
}
-
- if (dep_type == SourceFileDependencyType.SOURCE) {
- source_includes.concat (t.get_cheader_filenames ());
+ } else if (sym.node is Property) {
+ t = (DataType) sym.parent_symbol.node;
+ } else if (sym.node is FormalParameter) {
+ var fp = (FormalParameter) sym.node;
+ t = fp.type_reference.data_type;
+ if (t == null) {
+ /* generic type parameter */
return;
}
+ } else {
+ return;
+ }
+
+ if (dep_type == SourceFileDependencyType.SOURCE) {
+ source_includes.concat (t.get_cheader_filenames ());
+ return;
+ }
- if (t.source_reference.file.pkg) {
- /* external package */
- header_external_includes.concat (t.get_cheader_filenames ());
- return;
- }
-
- if (dep_type == SourceFileDependencyType.HEADER_FULL || !t.is_reference_type ()) {
- header_internal_includes.concat (t.get_cheader_filenames ());
- header_internal_full_dependencies.append (t.source_reference.file);
- }
-
- header_internal_dependencies.append (t.source_reference.file);
+ if (t.source_reference.file.pkg) {
+ /* external package */
+ header_external_includes.concat (t.get_cheader_filenames ());
+ return;
+ }
+
+ if (dep_type == SourceFileDependencyType.HEADER_FULL || !t.is_reference_type ()) {
+ header_internal_includes.concat (t.get_cheader_filenames ());
+ header_internal_full_dependencies.append (t.source_reference.file);
}
+
+ header_internal_dependencies.append (t.source_reference.file);
+ }
+
+ /**
+ * Returns the list of externel includes the generated C header file
+ * requires.
+ *
+ * @return external include list for C header file
+ */
+ public List<string> get_header_external_includes () {
+ return 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) {
+ header_internal_includes.append (include);
+ }
+
+ /**
+ * Returns the list of package-internal includes the generated C header file
+ * requires.
+ *
+ * @return internal include list for C header file
+ */
+ public List<string> get_header_internal_includes () {
+ return header_internal_includes;
+ }
+
+ /**
+ * Returns the list of includes the generated C source file requires.
+ *
+ * @return include list for C source file
+ */
+ public List<string> get_source_includes () {
+ return source_includes;
}
- public enum SourceFileDependencyType {
- HEADER_FULL,
- HEADER_SHALLOW,
- SOURCE
+ /**
+ * Returns the list of source files the generated C header file requires
+ * definitely.
+ *
+ * @return definite source file dependencies
+ */
+ public List<SourceFile> get_header_internal_full_dependencies () {
+ return header_internal_full_dependencies;
}
+
+ /**
+ * Returns the list of source files the generated C header file loosely
+ * depends on.
+ *
+ * @return loose source file dependencies
+ */
+ public List<SourceFile> get_header_internal_dependencies () {
+ return header_internal_dependencies;
+ }
+}
+
+public enum Vala.SourceFileDependencyType {
+ HEADER_FULL,
+ HEADER_SHALLOW,
+ SOURCE
}
Symbol root;
Symbol current_type;
Symbol current_symbol;
+ SourceFile current_source_file;
/**
* Build the symbol tree for the specified code context.
context.accept (this);
}
+ public override void visit_begin_source_file (SourceFile! file) {
+ current_source_file = file;
+ }
+
public override void visit_begin_namespace (Namespace! ns) {
if (ns.name == null) {
ns.symbol = root;
}
m.this_parameter = new FormalParameter (name = "this", type_reference = new TypeReference ());
- m.this_parameter.type_reference.type = (DataType) m.symbol.parent_symbol.node;
+ m.this_parameter.type_reference.data_type = (DataType) m.symbol.parent_symbol.node;
m.this_parameter.symbol = new Symbol (node = m.this_parameter);
current_symbol.add (m.this_parameter.name, m.this_parameter.symbol);
}
current_symbol = prop.symbol;
prop.this_parameter = new FormalParameter (name = "this", type_reference = new TypeReference ());
- prop.this_parameter.type_reference.type = (DataType) prop.symbol.parent_symbol.node;
+ prop.this_parameter.type_reference.data_type = (DataType) prop.symbol.parent_symbol.node;
prop.this_parameter.symbol = new Symbol (node = prop.this_parameter);
current_symbol.add (prop.this_parameter.name, prop.this_parameter.symbol);
}
acc.symbol = new Symbol (node = acc);
acc.symbol.parent_symbol = current_symbol;
current_symbol = acc.symbol;
+
+ if (current_source_file.pkg) {
+ return;
+ }
if (acc.writable || acc.construct_) {
acc.value_parameter = new FormalParameter (name = "value", type_reference = ((Property) current_symbol.parent_symbol.node).type_reference);
public override void visit_end_class (Class! cl) {
foreach (TypeReference type in cl.get_base_types ()) {
- if (type.type is Class) {
+ if (type.data_type is Class) {
if (cl.base_class != null) {
- Report.error (type.source_reference, "%s: Classes cannot have multiple base classes (`%s' and `%s')".printf (cl.symbol.get_full_name (), cl.base_class.symbol.get_full_name (), type.type.symbol.get_full_name ()));
+ Report.error (type.source_reference, "%s: Classes cannot have multiple base classes (`%s' and `%s')".printf (cl.symbol.get_full_name (), cl.base_class.symbol.get_full_name (), type.data_type.symbol.get_full_name ()));
return;
}
- cl.base_class = (Class) type.type;
+ cl.base_class = (Class) type.data_type;
}
}
if (cl.base_class == null && cl != object_class) {
current_scope = current_scope.parent_symbol;
}
+ public override void visit_formal_parameter (FormalParameter! p) {
+ if (!p.ellipsis && p.type_reference.is_ref) {
+ if ((p.type_reference.data_type != null &&
+ p.type_reference.data_type.is_reference_type ()) ||
+ p.type_reference.type_parameter != null) {
+ p.type_reference.takes_ownership = true;
+ } else {
+ p.type_reference.reference_to_value_type = true;
+ }
+ }
+ }
+
public override void visit_namespace_reference (NamespaceReference! ns) {
ns.namespace_symbol = current_scope.lookup (ns.name);
if (ns.namespace_symbol == null) {
if (sym.node is TypeParameter) {
type.type_parameter = (TypeParameter) sym.node;
} else {
- type.type = (DataType) sym.node;
+ type.data_type = (DataType) sym.node;
}
} else {
var ns_symbol = root_symbol.lookup (type.namespace_name);
Report.error (type.source_reference, "The type name `%s' does not exist in the namespace `%s'".printf (type.type_name, type.namespace_name));
return;
}
- type.type = (DataType) sym.node;
+ type.data_type = (DataType) sym.node;
}
- if (type.type != null && !type.type.is_reference_type ()) {
- /* reset is_lvalue_ref for contexts where types
+ if (type.data_type != null && !type.data_type.is_reference_type ()) {
+ /* reset takes_ownership for contexts where types
* are ref by default (field declarations)
*/
- type.is_lvalue_ref = false;
+ type.takes_ownership = false;
}
/* check for array */
if (type.array) {
- type.type = type.type.get_array ();
+ type.data_type = type.data_type.get_array ();
}
}
}
using GLib;
-namespace Vala {
- public class TypeReference : CodeNode {
- public string namespace_name { get; construct; }
- public string type_name { get; construct; }
- public bool is_ref { get; set; }
- public bool is_lvalue_ref { get; set; }
- public bool is_weak { get; set; }
- public bool is_out { get; set; }
- public bool array { get; set; }
- public bool array_own { get; set; }
- public bool non_null { get; set; }
- public weak DataType type;
- public TypeParameter type_parameter;
- public bool floating_reference { get; set; }
+/**
+ * A reference to a data type. This is used to specify static types of
+ * expressions.
+ */
+public class Vala.TypeReference : CodeNode {
+ /**
+ * Specifies that the expression is a reference to a value type.
+ * References to value types are used in ref parameters.
+ */
+ public bool reference_to_value_type { get; set; }
+
+ /**
+ * Specifies that the expression transfers ownership of its value.
+ */
+ public bool transfers_ownership { get; set; }
+
+ /**
+ * Specifies that the expression assumes ownership if used as an lvalue
+ * in an assignment.
+ */
+ public bool takes_ownership { get; set; }
- List<TypeReference> type_argument_list;
+ /**
+ * Specifies that the expression is a reference to a reference type.
+ * References to reference types are used in out parameters.
+ */
+ public bool is_out { get; set; }
+
+ /**
+ * Specifies that the expression is guaranteed not to be null.
+ */
+ public bool non_null { get; set; }
+
+ /**
+ * The referred data type.
+ */
+ public weak DataType data_type { get; set; }
+
+ /**
+ * The referred generic type parameter.
+ */
+ public TypeParameter type_parameter { get; set; }
+
+ /**
+ * Specifies that the expression transfers a floating reference.
+ */
+ public bool floating_reference { get; set; }
+
+ /**
+ * The name of the namespace containing the referred data type. May only
+ * be used with unresolved type references.
+ */
+ public string namespace_name { get; set; }
+
+ /**
+ * The name of the referred data type. May only be used with unresolved
+ * type references.
+ */
+ public string type_name { get; set; }
+
+ /**
+ * Specifies that this is referring to an array. May only be used with
+ * unresolved type references.
+ */
+ public bool array { get; set; }
+
+ /**
+ * The ref modifier has been specified, may only be used with unresolved
+ * type references.
+ */
+ public bool is_ref { get; set; }
+
+ /**
+ * The weak modifier has been specified. May only be used with
+ * unresolved type references.
+ */
+ public bool is_weak { get; set; }
- public static ref TypeReference new (string ns, string type_name, SourceReference source) {
- return (new TypeReference (namespace_name = ns, type_name = type_name, source_reference = source));
- }
+ private List<TypeReference> type_argument_list;
+
+ /**
+ * Creates a new type reference.
+ *
+ * @param ns optional namespace name
+ * @param type_name type symbol name
+ * @param source reference to source code
+ * @return newly created type reference
+ */
+ public static ref TypeReference! new (string ns, string! type_name, SourceReference source) {
+ return (new TypeReference (namespace_name = ns, type_name = type_name, source_reference = source));
+ }
- public static ref TypeReference new_from_expression (Expression expr, SourceReference source) {
- string ns = null;
- string type_name = null;
- if (expr is MemberAccess) {
- MemberAccess ma = (MemberAccess) expr;
- if (ma.inner != null) {
- if (ma.inner is MemberAccess) {
- var simple = (MemberAccess) ma.inner;
- return (new TypeReference (namespace_name = simple.member_name, type_name = ma.member_name, source_reference = source));
- }
- } else {
- return (new TypeReference (type_name = ma.member_name, source_reference = source));
+ /**
+ * Creates a new type reference from a code expression.
+ *
+ * @param expr member access expression
+ * @param source reference to source code
+ * @return newly created type reference
+ */
+ public static ref TypeReference new_from_expression (Expression! expr, SourceReference source) {
+ string ns = null;
+ string type_name = null;
+ if (expr is MemberAccess) {
+ MemberAccess ma = (MemberAccess) expr;
+ if (ma.inner != null) {
+ if (ma.inner is MemberAccess) {
+ var simple = (MemberAccess) ma.inner;
+ return (new TypeReference (namespace_name = simple.member_name, type_name = ma.member_name, source_reference = source));
}
+ } else {
+ return (new TypeReference (type_name = ma.member_name, source_reference = source));
}
- /* FIXME: raise error */
- return null;
- }
-
- public void add_type_argument (TypeReference! arg) {
- type_argument_list.append (arg);
}
- public ref List<TypeReference> get_type_arguments () {
- return type_argument_list.copy ();
- }
-
- public override void accept (CodeVisitor! visitor) {
- foreach (TypeReference type_arg in type_argument_list) {
- type_arg.accept (visitor);
- }
-
- visitor.visit_type_reference (this);
+ Report.error (source, "Type reference must be simple name or member access expression");
+ return null;
+ }
+
+ /**
+ * Appends the specified type as generic type argument.
+ *
+ * @param arg a type reference
+ */
+ public void add_type_argument (TypeReference! arg) {
+ type_argument_list.append (arg);
+ }
+
+ /**
+ * Returns a copy of the list of generic type arguments.
+ *
+ * @return type argument list
+ */
+ public ref List<TypeReference> get_type_arguments () {
+ return type_argument_list.copy ();
+ }
+
+ public override void accept (CodeVisitor! visitor) {
+ foreach (TypeReference type_arg in type_argument_list) {
+ type_arg.accept (visitor);
}
+
+ visitor.visit_type_reference (this);
+ }
- public ref string get_cname (bool var_type = false) {
- if (type == null && type_parameter == null) {
- if (var_type) {
- return "gpointer";
- } else {
- return "void";
- }
- }
-
- string ptr;
- string arr;
- if (type_parameter == null && !type.is_reference_type () && !is_ref) {
- ptr = "";
- } else if (((type_parameter != null || type.is_reference_type ()) && !is_out) || is_ref) {
- ptr = "*";
- } else {
- ptr = "**";
- }
- if (type != null) {
- return type.get_cname ().concat (ptr, arr, null);
- } else if (type_parameter != null) {
- return "gpointer".concat (ptr, arr, null);
+ /**
+ * Returns the name and qualifiers of this type as it is used in C code.
+ *
+ * @return the type string to be used in C code
+ */
+ public ref string get_cname (bool var_type = false) {
+ if (data_type == null && type_parameter == null) {
+ if (var_type) {
+ return "gpointer";
} else {
- /* raise error */
- Report.error (source_reference, "unresolved type reference");
- return null;
+ return "void";
}
}
+
+ string ptr;
+ string arr;
+ if (type_parameter == null && !data_type.is_reference_type () && !reference_to_value_type) {
+ ptr = "";
+ } else if (((type_parameter != null || data_type.is_reference_type ()) && !is_out) || reference_to_value_type) {
+ ptr = "*";
+ } else {
+ ptr = "**";
+ }
+ if (data_type != null) {
+ return data_type.get_cname ().concat (ptr, arr, null);
+ } else if (type_parameter != null) {
+ return "gpointer".concat (ptr, arr, null);
+ } else {
+ /* raise error */
+ Report.error (source_reference, "unresolved type reference");
+ return null;
+ }
+ }
- public ref string get_const_cname () {
- string ptr;
- DataType t;
- /* FIXME: dirty hack to make constant arrays possible */
- if (type is Array) {
- t = ((Array)type).element_type;
- } else {
- t = type;
- }
- if (!t.is_reference_type ()) {
- ptr = "";
- } else {
- ptr = "*";
- }
-
- return "const %s%s".printf (t.get_cname (), ptr);
+ /**
+ * Returns the name and qualifiers of this type as it is used in C code
+ * in a const declaration.
+ *
+ * @return the type string to be used in C code const declarations
+ */
+ public ref string get_const_cname () {
+ string ptr;
+ DataType t;
+ /* FIXME: dirty hack to make constant arrays possible */
+ if (data_type is Array) {
+ t = ((Array) data_type).element_type;
+ } else {
+ t = data_type;
}
-
- public ref string get_upper_case_cname (string infix) {
- return type.get_upper_case_cname (infix);
+ if (!t.is_reference_type ()) {
+ ptr = "";
+ } else {
+ ptr = "*";
}
- public ref string to_string () {
- if (type != null) {
- return type.symbol.get_full_name ();
- } else if (type_parameter != null) {
- return type_parameter.name;
- } else {
- return "null";
- }
+ return "const %s%s".printf (t.get_cname (), ptr);
+ }
+
+ /**
+ * Returns a user-readable name of the type corresponding to this type
+ * reference.
+ *
+ * @return display name
+ */
+ public ref string! to_string () {
+ if (data_type != null) {
+ return data_type.symbol.get_full_name ();
+ } else if (type_parameter != null) {
+ return type_parameter.name;
+ } else {
+ return "null";
}
+ }
+
+ /**
+ * Creates a shallow copy of this type reference. May only be used with
+ * resolved type references.
+ *
+ * @return copy of this type reference
+ */
+ public ref TypeReference! copy () {
+ var result = new TypeReference ();
+ result.reference_to_value_type = reference_to_value_type;
+ result.transfers_ownership = transfers_ownership;
+ result.takes_ownership = takes_ownership;
+ result.is_out = is_out;
+ result.non_null = non_null;
+ result.data_type = data_type;
+ result.type_parameter = type_parameter;
- public ref TypeReference copy () {
- var result = new TypeReference ();
- result.is_ref = is_ref;
- result.is_lvalue_ref = is_lvalue_ref;
- result.is_weak = is_weak;
- result.is_out = is_out;
- result.array = array;
- result.array_own = array_own;
- result.non_null = non_null;
- result.type = type;
- result.type_parameter = type_parameter;
-
- return result;
+ return result;
+ }
+
+ /**
+ * Checks two type references for equality. May only be used with
+ * resolved type references.
+ *
+ * @param type2 a type reference
+ * @return true if this type reference is equal to type2, false
+ * otherwise
+ */
+ public bool equals (TypeReference! type2) {
+ if (type2.reference_to_value_type != reference_to_value_type) {
+ return false;
+ }
+ if (type2.transfers_ownership != transfers_ownership) {
+ return false;
+ }
+ if (type2.takes_ownership != takes_ownership) {
+ return false;
+ }
+ if (type2.is_out != is_out) {
+ return false;
+ }
+ if (type2.non_null != non_null) {
+ return false;
+ }
+ if (type2.data_type != data_type) {
+ return false;
+ }
+ if (type2.type_parameter != type_parameter) {
+ return false;
+ }
+ if (type2.floating_reference != floating_reference) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks whether this type reference is at least as strict as the
+ * specified type reference type2.
+ *
+ * @param type2 a type reference
+ * @return true if this type reference is stricter or equal
+ */
+ public bool stricter (TypeReference! type2) {
+ if (type2.reference_to_value_type != reference_to_value_type) {
+ return false;
+ }
+ if (type2.transfers_ownership != transfers_ownership) {
+ return false;
+ }
+ if (type2.takes_ownership != takes_ownership) {
+ return false;
+ }
+ if (type2.is_out != is_out) {
+ return false;
}
- public bool equals (TypeReference! type2) {
- if (type2.is_ref != is_ref) {
- return false;
- }
- if (type2.is_lvalue_ref != is_lvalue_ref) {
- return false;
- }
- if (type2.is_weak != is_weak) {
- return false;
- }
- if (type2.is_out != is_out) {
- return false;
- }
- if (type2.array != array) {
- return false;
- }
- if (type2.array_own != array_own) {
- return false;
- }
- if (type2.non_null != non_null) {
- return false;
- }
- if (type2.type != type) {
- return false;
- }
- if (type2.type_parameter != type_parameter) {
- return false;
- }
- if (type2.floating_reference != floating_reference) {
- return false;
- }
-
- return true;
+ if (type2.non_null && !non_null) {
+ return false;
+ }
+
+ if (type2.data_type != data_type) {
+ // FIXME: allow this type reference to refer to a
+ // subtype of the type type2 is referring to
+ return false;
}
+ if (type2.type_parameter != type_parameter) {
+ return false;
+ }
+ if (type2.floating_reference != floating_reference) {
+ return false;
+ }
+
+ return true;
}
}