From: Jürg Billeter Date: Wed, 5 Nov 2008 21:54:46 +0000 (+0000) Subject: Move member access checking to MemberAccess.check X-Git-Tag: VALA_0_5_2~125 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f412f7cf1a4c66f20f445c5eb215eda2b86f702;p=thirdparty%2Fvala.git Move member access checking to MemberAccess.check 2008-11-05 Jürg Billeter * vala/valamemberaccess.vala: * vala/valasemanticanalyzer.vala: Move member access checking to MemberAccess.check svn path=/trunk/; revision=1986 --- diff --git a/ChangeLog b/ChangeLog index 800c38106..7c17eb0fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-05 Jürg Billeter + + * vala/valamemberaccess.vala: + * vala/valasemanticanalyzer.vala: + + Move member access checking to MemberAccess.check + 2008-11-05 Jürg Billeter * vala/valabinaryexpression.vala: diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala index 7436f067c..153453a4b 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -174,4 +174,355 @@ public class Vala.MemberAccess : Expression { return false; } } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + Symbol base_symbol = null; + FormalParameter this_parameter = null; + bool may_access_instance_members = false; + + symbol_reference = null; + + if (qualified) { + base_symbol = analyzer.root_symbol; + symbol_reference = analyzer.root_symbol.scope.lookup (member_name); + } else if (inner == null) { + if (member_name == "this") { + if (!analyzer.is_in_instance_method ()) { + error = true; + Report.error (source_reference, "This access invalid outside of instance methods"); + return false; + } + } + + base_symbol = analyzer.current_symbol; + + var sym = analyzer.current_symbol; + while (sym != null && symbol_reference == null) { + if (this_parameter == null) { + if (sym is CreationMethod) { + var cm = (CreationMethod) sym; + this_parameter = cm.this_parameter; + may_access_instance_members = true; + } else if (sym is Property) { + var prop = (Property) sym; + this_parameter = prop.this_parameter; + may_access_instance_members = true; + } else if (sym is Constructor) { + var c = (Constructor) sym; + this_parameter = c.this_parameter; + may_access_instance_members = true; + } else if (sym is Destructor) { + var d = (Destructor) sym; + this_parameter = d.this_parameter; + may_access_instance_members = true; + } else if (sym is Method) { + var m = (Method) sym; + this_parameter = m.this_parameter; + may_access_instance_members = (m.binding == MemberBinding.INSTANCE); + } + } + + symbol_reference = analyzer.symbol_lookup_inherited (sym, member_name); + sym = sym.parent_symbol; + } + + if (symbol_reference == null) { + foreach (UsingDirective ns in analyzer.current_using_directives) { + var local_sym = ns.namespace_symbol.scope.lookup (member_name); + if (local_sym != null) { + if (symbol_reference != null) { + error = true; + Report.error (source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (member_name, symbol_reference.get_full_name (), local_sym.get_full_name ())); + return false; + } + symbol_reference = local_sym; + } + } + } + } else { + if (inner.error) { + /* if there was an error in the inner expression, skip this check */ + error = true; + return false; + } + + if (pointer_member_access) { + var pointer_type = inner.value_type as PointerType; + if (pointer_type != null && pointer_type.base_type is ValueType) { + // transform foo->bar to (*foo).bar + inner = new PointerIndirection (inner, source_reference); + inner.accept (analyzer); + pointer_member_access = false; + } + } + + if (inner is MemberAccess) { + var ma = (MemberAccess) inner; + if (ma.prototype_access) { + error = true; + Report.error (source_reference, "Access to instance member `%s' denied".printf (inner.symbol_reference.get_full_name ())); + return false; + } + } + + if (inner is MemberAccess || inner is BaseAccess) { + base_symbol = inner.symbol_reference; + + if (symbol_reference == null && (base_symbol is Namespace || base_symbol is TypeSymbol)) { + symbol_reference = base_symbol.scope.lookup (member_name); + if (inner is BaseAccess) { + // inner expression is base access + // access to instance members of the base type possible + may_access_instance_members = true; + } + } + } + + if (symbol_reference == null && inner.value_type != null) { + if (pointer_member_access) { + symbol_reference = inner.value_type.get_pointer_member (member_name); + } else { + if (inner.value_type.data_type != null) { + base_symbol = inner.value_type.data_type; + } + symbol_reference = inner.value_type.get_member (member_name); + } + if (symbol_reference != null) { + // inner expression is variable, field, or parameter + // access to instance members of the corresponding type possible + may_access_instance_members = true; + } + } + + if (symbol_reference == null && inner.value_type != null && inner.value_type.is_dynamic) { + // allow late bound members for dynamic types + var dynamic_object_type = (ObjectType) inner.value_type; + if (parent_node is InvocationExpression) { + var invoc = (InvocationExpression) parent_node; + if (invoc.call == this) { + // dynamic method + DataType ret_type; + if (invoc.target_type != null) { + ret_type = invoc.target_type.copy (); + ret_type.value_owned = true; + } else if (invoc.parent_node is ExpressionStatement) { + ret_type = new VoidType (); + } else { + // expect dynamic object of the same type + ret_type = inner.value_type.copy (); + } + var m = new DynamicMethod (inner.value_type, member_name, ret_type, source_reference); + m.invocation = invoc; + m.add_error_type (new ErrorType (null, null)); + m.access = SymbolAccessibility.PUBLIC; + m.add_parameter (new FormalParameter.with_ellipsis ()); + dynamic_object_type.type_symbol.scope.add (null, m); + symbol_reference = m; + } + } else if (parent_node is Assignment) { + var a = (Assignment) parent_node; + if (a.left == this + && (a.operator == AssignmentOperator.ADD + || a.operator == AssignmentOperator.SUB)) { + // dynamic signal + var s = new DynamicSignal (inner.value_type, member_name, new VoidType (), source_reference); + s.handler = a.right; + s.access = SymbolAccessibility.PUBLIC; + dynamic_object_type.type_symbol.scope.add (null, s); + symbol_reference = s; + } else if (a.left == this) { + // dynamic property assignment + var prop = new DynamicProperty (inner.value_type, member_name, source_reference); + prop.access = SymbolAccessibility.PUBLIC; + prop.set_accessor = new PropertyAccessor (false, true, false, null, prop.source_reference); + prop.set_accessor.access = SymbolAccessibility.PUBLIC; + prop.owner = inner.value_type.data_type.scope; + dynamic_object_type.type_symbol.scope.add (null, prop); + symbol_reference = prop; + } + } + if (symbol_reference == null) { + // dynamic property read access + var prop = new DynamicProperty (inner.value_type, member_name, source_reference); + if (target_type != null) { + prop.property_type = target_type; + } else { + // expect dynamic object of the same type + prop.property_type = inner.value_type.copy (); + } + prop.access = SymbolAccessibility.PUBLIC; + prop.get_accessor = new PropertyAccessor (true, false, false, null, prop.source_reference); + prop.get_accessor.access = SymbolAccessibility.PUBLIC; + prop.owner = inner.value_type.data_type.scope; + dynamic_object_type.type_symbol.scope.add (null, prop); + symbol_reference = prop; + } + if (symbol_reference != null) { + may_access_instance_members = true; + } + } + } + + if (symbol_reference == null) { + error = true; + + string base_type_name = "(null)"; + if (inner != null && inner.value_type != null) { + base_type_name = inner.value_type.to_string (); + } else if (base_symbol != null) { + base_type_name = base_symbol.get_full_name (); + } + + Report.error (source_reference, "The name `%s' does not exist in the context of `%s'".printf (member_name, base_type_name)); + return false; + } + + var member = symbol_reference; + var access = SymbolAccessibility.PUBLIC; + bool instance = false; + bool klass = false; + if (member is Field) { + var f = (Field) member; + access = f.access; + instance = (f.binding == MemberBinding.INSTANCE); + klass = (f.binding == MemberBinding.CLASS); + } else if (member is Method) { + var m = (Method) member; + access = m.access; + if (!(m is CreationMethod)) { + instance = (m.binding == MemberBinding.INSTANCE); + } + klass = (m.binding == MemberBinding.CLASS); + } else if (member is Property) { + var prop = (Property) member; + if (!prop.check (analyzer)) { + error = true; + return false; + } + access = prop.access; + if (lvalue) { + if (prop.set_accessor == null) { + error = true; + Report.error (source_reference, "Property `%s' is read-only".printf (prop.get_full_name ())); + return false; + } + if (prop.access == SymbolAccessibility.PUBLIC) { + access = prop.set_accessor.access; + } else if (prop.access == SymbolAccessibility.PROTECTED + && prop.set_accessor.access != SymbolAccessibility.PUBLIC) { + access = prop.set_accessor.access; + } + } else { + if (prop.get_accessor == null) { + error = true; + Report.error (source_reference, "Property `%s' is write-only".printf (prop.get_full_name ())); + return false; + } + if (prop.access == SymbolAccessibility.PUBLIC) { + access = prop.get_accessor.access; + } else if (prop.access == SymbolAccessibility.PROTECTED + && prop.get_accessor.access != SymbolAccessibility.PUBLIC) { + access = prop.get_accessor.access; + } + } + instance = (prop.binding == MemberBinding.INSTANCE); + } else if (member is Signal) { + instance = true; + } + + if (access == SymbolAccessibility.PRIVATE) { + var target_type = member.parent_symbol; + + bool in_target_type = false; + for (Symbol this_symbol = analyzer.current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol) { + if (target_type == this_symbol) { + in_target_type = true; + break; + } + } + + if (!in_target_type) { + error = true; + Report.error (source_reference, "Access to private member `%s' denied".printf (member.get_full_name ())); + return false; + } + } + if ((instance || klass) && !may_access_instance_members) { + prototype_access = true; + + if (symbol_reference is Method) { + // also set static type for prototype access + // required when using instance methods as delegates in constants + // TODO replace by MethodPrototype + value_type = analyzer.get_value_type_for_symbol (symbol_reference, lvalue); + } else if (symbol_reference is Field) { + value_type = new FieldPrototype ((Field) symbol_reference); + } + } else { + // implicit this access + if (instance && inner == null) { + inner = new MemberAccess (null, "this", source_reference); + inner.value_type = this_parameter.parameter_type.copy (); + inner.symbol_reference = this_parameter; + } + + value_type = analyzer.get_value_type_for_symbol (symbol_reference, lvalue); + + // resolve generic return values + if (value_type != null && value_type.type_parameter != null) { + if (inner != null) { + value_type = analyzer.get_actual_type (inner.value_type, symbol_reference, value_type, this); + if (value_type == null) { + return false; + } + } + } + + if (symbol_reference is Method) { + var m = (Method) symbol_reference; + + Method base_method; + if (m.base_method != null) { + base_method = m.base_method; + } else if (m.base_interface_method != null) { + base_method = m.base_interface_method; + } else { + base_method = m; + } + + if (instance && base_method.parent_symbol != null) { + inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) base_method.parent_symbol); + } + } else if (symbol_reference is Property) { + var prop = (Property) symbol_reference; + + Property base_property; + if (prop.base_property != null) { + base_property = prop.base_property; + } else if (prop.base_interface_property != null) { + base_property = prop.base_interface_property; + } else { + base_property = prop; + } + + if (instance && base_property.parent_symbol != null) { + inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) base_property.parent_symbol); + } + } else if ((symbol_reference is Field + || symbol_reference is Signal) + && instance && symbol_reference.parent_symbol != null) { + inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) symbol_reference.parent_symbol); + } + } + + analyzer.current_source_file.add_symbol_dependency (symbol_reference, SourceFileDependencyType.SOURCE); + + return !error; + } } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 6d5a4d6b0..e63803687 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -30,14 +30,14 @@ using Gee; public class Vala.SemanticAnalyzer : CodeVisitor { public CodeContext context { get; set; } - Symbol root_symbol; + public Symbol root_symbol; public Symbol current_symbol { get; set; } public SourceFile current_source_file { get; set; } DataType current_return_type; Class current_class; Struct current_struct; - Gee.List current_using_directives; + public Gee.List current_using_directives; public DataType bool_type; public DataType string_type; @@ -1401,7 +1401,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { expr.value_type = new NullType (expr.source_reference); } - private DataType? get_value_type_for_symbol (Symbol sym, bool lvalue) { + public DataType? get_value_type_for_symbol (Symbol sym, bool lvalue) { if (sym is Field) { var f = (Field) sym; var type = f.field_type.copy (); @@ -1525,346 +1525,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } public override void visit_member_access (MemberAccess expr) { - Symbol base_symbol = null; - FormalParameter this_parameter = null; - bool may_access_instance_members = false; - - expr.symbol_reference = null; - - if (expr.qualified) { - base_symbol = root_symbol; - expr.symbol_reference = root_symbol.scope.lookup (expr.member_name); - } else if (expr.inner == null) { - if (expr.member_name == "this") { - if (!is_in_instance_method ()) { - expr.error = true; - Report.error (expr.source_reference, "This access invalid outside of instance methods"); - return; - } - } - - base_symbol = current_symbol; - - var sym = current_symbol; - while (sym != null && expr.symbol_reference == null) { - if (this_parameter == null) { - if (sym is CreationMethod) { - var cm = (CreationMethod) sym; - this_parameter = cm.this_parameter; - may_access_instance_members = true; - } else if (sym is Property) { - var prop = (Property) sym; - this_parameter = prop.this_parameter; - may_access_instance_members = true; - } else if (sym is Constructor) { - var c = (Constructor) sym; - this_parameter = c.this_parameter; - may_access_instance_members = true; - } else if (sym is Destructor) { - var d = (Destructor) sym; - this_parameter = d.this_parameter; - may_access_instance_members = true; - } else if (sym is Method) { - var m = (Method) sym; - this_parameter = m.this_parameter; - may_access_instance_members = (m.binding == MemberBinding.INSTANCE); - } - } - - expr.symbol_reference = symbol_lookup_inherited (sym, expr.member_name); - sym = sym.parent_symbol; - } - - if (expr.symbol_reference == null) { - foreach (UsingDirective ns in current_using_directives) { - var local_sym = ns.namespace_symbol.scope.lookup (expr.member_name); - if (local_sym != null) { - if (expr.symbol_reference != null) { - expr.error = true; - Report.error (expr.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (expr.member_name, expr.symbol_reference.get_full_name (), local_sym.get_full_name ())); - return; - } - expr.symbol_reference = local_sym; - } - } - } - } else { - if (expr.inner.error) { - /* if there was an error in the inner expression, skip this check */ - expr.error = true; - return; - } - - if (expr.pointer_member_access) { - var pointer_type = expr.inner.value_type as PointerType; - if (pointer_type != null && pointer_type.base_type is ValueType) { - // transform foo->bar to (*foo).bar - expr.inner = new PointerIndirection (expr.inner, expr.source_reference); - expr.inner.accept (this); - expr.pointer_member_access = false; - } - } - - if (expr.inner is MemberAccess) { - var ma = (MemberAccess) expr.inner; - if (ma.prototype_access) { - expr.error = true; - Report.error (expr.source_reference, "Access to instance member `%s' denied".printf (expr.inner.symbol_reference.get_full_name ())); - return; - } - } - - if (expr.inner is MemberAccess || expr.inner is BaseAccess) { - base_symbol = expr.inner.symbol_reference; - - if (expr.symbol_reference == null && (base_symbol is Namespace || base_symbol is TypeSymbol)) { - expr.symbol_reference = base_symbol.scope.lookup (expr.member_name); - if (expr.inner is BaseAccess) { - // inner expression is base access - // access to instance members of the base type possible - may_access_instance_members = true; - } - } - } - - if (expr.symbol_reference == null && expr.inner.value_type != null) { - if (expr.pointer_member_access) { - expr.symbol_reference = expr.inner.value_type.get_pointer_member (expr.member_name); - } else { - if (expr.inner.value_type.data_type != null) { - base_symbol = expr.inner.value_type.data_type; - } - expr.symbol_reference = expr.inner.value_type.get_member (expr.member_name); - } - if (expr.symbol_reference != null) { - // inner expression is variable, field, or parameter - // access to instance members of the corresponding type possible - may_access_instance_members = true; - } - } - - if (expr.symbol_reference == null && expr.inner.value_type != null && expr.inner.value_type.is_dynamic) { - // allow late bound members for dynamic types - var dynamic_object_type = (ObjectType) expr.inner.value_type; - if (expr.parent_node is InvocationExpression) { - var invoc = (InvocationExpression) expr.parent_node; - if (invoc.call == expr) { - // dynamic method - DataType ret_type; - if (invoc.target_type != null) { - ret_type = invoc.target_type.copy (); - ret_type.value_owned = true; - } else if (invoc.parent_node is ExpressionStatement) { - ret_type = new VoidType (); - } else { - // expect dynamic object of the same type - ret_type = expr.inner.value_type.copy (); - } - var m = new DynamicMethod (expr.inner.value_type, expr.member_name, ret_type, expr.source_reference); - m.invocation = invoc; - m.add_error_type (new ErrorType (null, null)); - m.access = SymbolAccessibility.PUBLIC; - m.add_parameter (new FormalParameter.with_ellipsis ()); - dynamic_object_type.type_symbol.scope.add (null, m); - expr.symbol_reference = m; - } - } else if (expr.parent_node is Assignment) { - var a = (Assignment) expr.parent_node; - if (a.left == expr - && (a.operator == AssignmentOperator.ADD - || a.operator == AssignmentOperator.SUB)) { - // dynamic signal - var s = new DynamicSignal (expr.inner.value_type, expr.member_name, new VoidType (), expr.source_reference); - s.handler = a.right; - s.access = SymbolAccessibility.PUBLIC; - dynamic_object_type.type_symbol.scope.add (null, s); - expr.symbol_reference = s; - } else if (a.left == expr) { - // dynamic property assignment - var prop = new DynamicProperty (expr.inner.value_type, expr.member_name, expr.source_reference); - prop.access = SymbolAccessibility.PUBLIC; - prop.set_accessor = new PropertyAccessor (false, true, false, null, prop.source_reference); - prop.set_accessor.access = SymbolAccessibility.PUBLIC; - prop.owner = expr.inner.value_type.data_type.scope; - dynamic_object_type.type_symbol.scope.add (null, prop); - expr.symbol_reference = prop; - } - } - if (expr.symbol_reference == null) { - // dynamic property read access - var prop = new DynamicProperty (expr.inner.value_type, expr.member_name, expr.source_reference); - if (expr.target_type != null) { - prop.property_type = expr.target_type; - } else { - // expect dynamic object of the same type - prop.property_type = expr.inner.value_type.copy (); - } - prop.access = SymbolAccessibility.PUBLIC; - prop.get_accessor = new PropertyAccessor (true, false, false, null, prop.source_reference); - prop.get_accessor.access = SymbolAccessibility.PUBLIC; - prop.owner = expr.inner.value_type.data_type.scope; - dynamic_object_type.type_symbol.scope.add (null, prop); - expr.symbol_reference = prop; - } - if (expr.symbol_reference != null) { - may_access_instance_members = true; - } - } - } - - if (expr.symbol_reference == null) { - expr.error = true; - - string base_type_name = "(null)"; - if (expr.inner != null && expr.inner.value_type != null) { - base_type_name = expr.inner.value_type.to_string (); - } else if (base_symbol != null) { - base_type_name = base_symbol.get_full_name (); - } - - Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, base_type_name)); - return; - } - - var member = expr.symbol_reference; - var access = SymbolAccessibility.PUBLIC; - bool instance = false; - bool klass = false; - if (member is Field) { - var f = (Field) member; - access = f.access; - instance = (f.binding == MemberBinding.INSTANCE); - klass = (f.binding == MemberBinding.CLASS); - } else if (member is Method) { - var m = (Method) member; - access = m.access; - if (!(m is CreationMethod)) { - instance = (m.binding == MemberBinding.INSTANCE); - } - klass = (m.binding == MemberBinding.CLASS); - } else if (member is Property) { - var prop = (Property) member; - if (!prop.check (this)) { - expr.error = true; - return; - } - access = prop.access; - if (expr.lvalue) { - if (prop.set_accessor == null) { - expr.error = true; - Report.error (expr.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ())); - return; - } - if (prop.access == SymbolAccessibility.PUBLIC) { - access = prop.set_accessor.access; - } else if (prop.access == SymbolAccessibility.PROTECTED - && prop.set_accessor.access != SymbolAccessibility.PUBLIC) { - access = prop.set_accessor.access; - } - } else { - if (prop.get_accessor == null) { - expr.error = true; - Report.error (expr.source_reference, "Property `%s' is write-only".printf (prop.get_full_name ())); - return; - } - if (prop.access == SymbolAccessibility.PUBLIC) { - access = prop.get_accessor.access; - } else if (prop.access == SymbolAccessibility.PROTECTED - && prop.get_accessor.access != SymbolAccessibility.PUBLIC) { - access = prop.get_accessor.access; - } - } - instance = (prop.binding == MemberBinding.INSTANCE); - } else if (member is Signal) { - instance = true; - } - - if (access == SymbolAccessibility.PRIVATE) { - var target_type = member.parent_symbol; - - bool in_target_type = false; - for (Symbol this_symbol = current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol) { - if (target_type == this_symbol) { - in_target_type = true; - break; - } - } - - if (!in_target_type) { - expr.error = true; - Report.error (expr.source_reference, "Access to private member `%s' denied".printf (member.get_full_name ())); - return; - } - } - if ((instance || klass) && !may_access_instance_members) { - expr.prototype_access = true; - - if (expr.symbol_reference is Method) { - // also set static type for prototype access - // required when using instance methods as delegates in constants - // TODO replace by MethodPrototype - expr.value_type = get_value_type_for_symbol (expr.symbol_reference, expr.lvalue); - } else if (expr.symbol_reference is Field) { - expr.value_type = new FieldPrototype ((Field) expr.symbol_reference); - } - } else { - // implicit this access - if (instance && expr.inner == null) { - expr.inner = new MemberAccess (null, "this", expr.source_reference); - expr.inner.value_type = this_parameter.parameter_type.copy (); - expr.inner.symbol_reference = this_parameter; - } - - expr.value_type = get_value_type_for_symbol (expr.symbol_reference, expr.lvalue); - - // resolve generic return values - if (expr.value_type != null && expr.value_type.type_parameter != null) { - if (expr.inner != null) { - expr.value_type = get_actual_type (expr.inner.value_type, expr.symbol_reference, expr.value_type, expr); - if (expr.value_type == null) { - return; - } - } - } - - if (expr.symbol_reference is Method) { - var m = (Method) expr.symbol_reference; - - Method base_method; - if (m.base_method != null) { - base_method = m.base_method; - } else if (m.base_interface_method != null) { - base_method = m.base_interface_method; - } else { - base_method = m; - } - - if (instance && base_method.parent_symbol != null) { - expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) base_method.parent_symbol); - } - } else if (expr.symbol_reference is Property) { - var prop = (Property) expr.symbol_reference; - - Property base_property; - if (prop.base_property != null) { - base_property = prop.base_property; - } else if (prop.base_interface_property != null) { - base_property = prop.base_interface_property; - } else { - base_property = prop; - } - - if (instance && base_property.parent_symbol != null) { - expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) base_property.parent_symbol); - } - } else if ((expr.symbol_reference is Field - || expr.symbol_reference is Signal) - && instance && expr.symbol_reference.parent_symbol != null) { - expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) expr.symbol_reference.parent_symbol); - } - } - - current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE); + expr.check (this); } public static DataType get_data_type_for_symbol (TypeSymbol sym) { @@ -2594,7 +2255,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } } - private bool is_in_instance_method () { + public bool is_in_instance_method () { var sym = current_symbol; while (sym != null) { if (sym is CreationMethod) {