From: Rico Tzschichholz Date: Wed, 15 Jul 2020 15:46:58 +0000 (+0200) Subject: vala: Use inheritted scopes of base-types/prerequisites to resolve symbols X-Git-Tag: 0.49.1~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=244b69cc5386b6707d603ea5a437ae3f02952c58;p=thirdparty%2Fvala.git vala: Use inheritted scopes of base-types/prerequisites to resolve symbols Fixes https://gitlab.gnome.org/GNOME/vala/issues/54 --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 42cad8968..6d9e32ebe 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -765,6 +765,8 @@ TESTS = \ parser/bug749576.vala \ resolver/class-base-cycle.test \ resolver/interface-prerequisite-cycle.test \ + resolver/peek-inner-types-ambiguous.test \ + resolver/peek-inner-types.vala \ resolver/struct-base-cycle.test \ ordering/delegate-class.vala \ ordering/delegate-enum.vala \ diff --git a/tests/resolver/peek-inner-types-ambiguous.test b/tests/resolver/peek-inner-types-ambiguous.test new file mode 100644 index 000000000..1a6108cc9 --- /dev/null +++ b/tests/resolver/peek-inner-types-ambiguous.test @@ -0,0 +1,34 @@ +Invalid Code + +namespace Baz { + public class Foo { + public class Bar { + } + + public interface IBar : Bar { + } + } + public interface IFoo : Foo { + public class Bar { + } + + public interface IBar : Bar { + } + } +} + +class Manam : Baz.Foo, Baz.IFoo { + public Bar? foo () { + return null; + } + + public IBar? ifoo () { + return null; + } +} + +void main () { + var manam = new Manam (); + manam.foo (); + manam.ifoo (); +} diff --git a/tests/resolver/peek-inner-types.vala b/tests/resolver/peek-inner-types.vala new file mode 100644 index 000000000..1c9ef8639 --- /dev/null +++ b/tests/resolver/peek-inner-types.vala @@ -0,0 +1,42 @@ +namespace Baz { + public class Foo { + public class Bar1 { + } + + public interface IBar1 : Bar1 { + } + } + public interface IFoo : Foo { + public class Bar2 { + } + + public interface IBar2 : Bar2 { + } + } +} + +class Manam : Baz.Foo, Baz.IFoo { + public Bar1? foo1 () { + return null; + } + + public IBar1? ifoo1 () { + return null; + } + + public Bar2? foo2 () { + return null; + } + + public IBar2? ifoo2 () { + return null; + } +} + +void main () { + var manam = new Manam (); + manam.foo1 (); + manam.ifoo1 (); + manam.foo2 (); + manam.ifoo2 (); +} diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala index 28365127a..3f9bc6de0 100644 --- a/vala/valasymbolresolver.vala +++ b/vala/valasymbolresolver.vala @@ -286,6 +286,49 @@ public class Vala.SymbolResolver : CodeVisitor { scope = scope.parent_scope; } + // Look for matches in inner types of base-types/prerequisites + ObjectTypeSymbol? current_symbol = null; + if (sym == null) { + scope = current_scope; + while (scope != null) { + if (scope.owner is ObjectTypeSymbol) { + current_symbol = (ObjectTypeSymbol) scope.owner; + break; + } + scope = scope.parent_scope; + } + } + if (current_symbol != null) { + unowned List types; + if (current_symbol is Class) { + types = ((Class) current_symbol).get_base_types (); + } else if (current_symbol is Interface) { + types = ((Interface) current_symbol).get_prerequisites (); + } else { + assert_not_reached (); + } + foreach (DataType type in types) { + if (type.type_symbol == null) { + continue; + } + + var local_sym = SemanticAnalyzer.symbol_lookup_inherited (type.type_symbol, unresolved_symbol.name); + + // only look for types and type containers + if (!(local_sym is Namespace || local_sym is TypeSymbol)) { + local_sym = null; + } + + if (local_sym != null && local_sym.access == SymbolAccessibility.PUBLIC) { + if (sym != null && sym != local_sym) { + unresolved_symbol.error = true; + Report.error (unresolved_symbol.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (unresolved_symbol.name, sym.get_full_name (), local_sym.get_full_name ())); + return null; + } + sym = local_sym; + } + } + } if (sym == null && unresolved_symbol.source_reference != null) { foreach (UsingDirective ns in unresolved_symbol.source_reference.using_directives) { if (ns.error || ns.namespace_symbol is UnresolvedSymbol) {