[vala/staging: 2/2] vala: Use inheritted scopes of base-types/prerequisites to resolve symbols
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging: 2/2] vala: Use inheritted scopes of base-types/prerequisites to resolve symbols
- Date: Wed, 15 Jul 2020 17:01:33 +0000 (UTC)
commit 244b69cc5386b6707d603ea5a437ae3f02952c58
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Wed Jul 15 17:46:58 2020 +0200
vala: Use inheritted scopes of base-types/prerequisites to resolve symbols
Fixes https://gitlab.gnome.org/GNOME/vala/issues/54
tests/Makefile.am | 2 ++
tests/resolver/peek-inner-types-ambiguous.test | 34 ++++++++++++++++++++
tests/resolver/peek-inner-types.vala | 42 +++++++++++++++++++++++++
vala/valasymbolresolver.vala | 43 ++++++++++++++++++++++++++
4 files changed, 121 insertions(+)
---
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<DataType> 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) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]