[vala/staging] vala: Improve check of generic type references in static contexts



commit 7b5c4f538cc1a1d1bf02b309f1e6286927901d87
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sun Jan 30 18:07:23 2022 +0100

    vala: Improve check of generic type references in static contexts
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/1284

 tests/Makefile.am                                  |  4 +++
 .../method-parameter-unknown-type-parameter-2.test |  9 ++++++
 .../method-parameter-unknown-type-parameter.test   |  9 ++++++
 .../method-return-unknown-type-parameter-2.test    | 10 +++++++
 .../method-return-unknown-type-parameter.test      | 10 +++++++
 vala/valamethod.vala                               | 34 ++++++++++++++++++++++
 6 files changed, 76 insertions(+)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cf9bd1e93..a502b3494 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -765,6 +765,10 @@ TESTS = \
        generics/parameter-invalid-initializer.test \
        generics/parameter-sizeof-initializer.vala \
        generics/member-dup-destroy.vala \
+       generics/method-parameter-unknown-type-parameter.test \
+       generics/method-parameter-unknown-type-parameter-2.test \
+       generics/method-return-unknown-type-parameter.test \
+       generics/method-return-unknown-type-parameter-2.test \
        generics/null-type.vala \
        generics/property-gobject-set.vala \
        generics/property-int-cast.vala \
diff --git a/tests/generics/method-parameter-unknown-type-parameter-2.test 
b/tests/generics/method-parameter-unknown-type-parameter-2.test
new file mode 100644
index 000000000..afbd77100
--- /dev/null
+++ b/tests/generics/method-parameter-unknown-type-parameter-2.test
@@ -0,0 +1,9 @@
+Invalid Code
+
+class Foo<G> {
+       static void bar (Foo<G> g) {
+       }
+}
+
+void main () {
+}
diff --git a/tests/generics/method-parameter-unknown-type-parameter.test 
b/tests/generics/method-parameter-unknown-type-parameter.test
new file mode 100644
index 000000000..f40ae8096
--- /dev/null
+++ b/tests/generics/method-parameter-unknown-type-parameter.test
@@ -0,0 +1,9 @@
+Invalid Code
+
+class Foo<G> {
+       static void bar (G g) {
+       }
+}
+
+void main () {
+}
diff --git a/tests/generics/method-return-unknown-type-parameter-2.test 
b/tests/generics/method-return-unknown-type-parameter-2.test
new file mode 100644
index 000000000..aef59eda8
--- /dev/null
+++ b/tests/generics/method-return-unknown-type-parameter-2.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+class Foo<G> {
+       static Foo<G> bar () {
+               return null;
+       }
+}
+
+void main () {
+}
diff --git a/tests/generics/method-return-unknown-type-parameter.test 
b/tests/generics/method-return-unknown-type-parameter.test
new file mode 100644
index 000000000..f25d37183
--- /dev/null
+++ b/tests/generics/method-return-unknown-type-parameter.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+class Foo<G> {
+       static G bar () {
+               return null;
+       }
+}
+
+void main () {
+}
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index fc8491594..2794cd48e 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -890,6 +890,19 @@ public class Vala.Method : Subroutine, Callable {
                        Report.error (source_reference, "[Print] methods must have exactly one parameter of 
type `string'");
                }
 
+               // Collect generic type references
+               // TODO Can this be done in the SymbolResolver?
+               List<GenericType> referenced_generics = new ArrayList<GenericType> ();
+               var traverse = new TraverseVisitor (node => {
+                       if (node is GenericType) {
+                               referenced_generics.add ((GenericType) node);
+                               return TraverseStatus.STOP;
+                       }
+                       return TraverseStatus.CONTINUE;
+               });
+
+               return_type.accept (traverse);
+
                var optional_param = false;
                var params_array_param = false;
                var ellipsis_param = false;
@@ -907,6 +920,9 @@ public class Vala.Method : Subroutine, Callable {
                                Report.error (param.source_reference, "Variadic parameters are not supported 
for async methods");
                                return false;
                        }
+
+                       param.accept_children (traverse);
+
                        // TODO: begin and end parameters must be checked separately for coroutines
                        if (coroutine) {
                                continue;
@@ -955,6 +971,24 @@ public class Vala.Method : Subroutine, Callable {
                        }
                }
 
+               // Check if referenced type-parameters are present
+               // TODO Can this be done in the SymbolResolver?
+               if (binding == MemberBinding.STATIC && parent_symbol is Class && !((Class) 
parent_symbol).is_compact) {
+                       Iterator<GenericType> ref_generics_it = referenced_generics.iterator ();
+                       while (ref_generics_it.next ()) {
+                               var ref_generics = ref_generics_it.get ();
+                               foreach (var type_param in get_type_parameters ()) {
+                                       if (ref_generics.type_parameter.name == type_param.name) {
+                                               ref_generics_it.remove ();
+                                       }
+                               }
+                       }
+                       foreach (var type in referenced_generics) {
+                               error = true;
+                               Report.error (type.source_reference, "The type name `%s' could not be found", 
type.type_parameter.name);
+                       }
+               }
+
                if (coroutine) {
                        // TODO: async methods with out-parameters before in-parameters are not supported
                        bool requires_pointer = false;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]