]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Improve check of generic type references in static contexts
authorRico Tzschichholz <ricotz@ubuntu.com>
Sun, 30 Jan 2022 17:07:23 +0000 (18:07 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sun, 30 Jan 2022 17:10:05 +0000 (18:10 +0100)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/1284

tests/Makefile.am
tests/generics/method-parameter-unknown-type-parameter-2.test [new file with mode: 0644]
tests/generics/method-parameter-unknown-type-parameter.test [new file with mode: 0644]
tests/generics/method-return-unknown-type-parameter-2.test [new file with mode: 0644]
tests/generics/method-return-unknown-type-parameter.test [new file with mode: 0644]
vala/valamethod.vala

index cf9bd1e933a0fbe656270fb7e33aadef25f37614..a502b3494e231099498873b456e525b585878b82 100644 (file)
@@ -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 (file)
index 0000000..afbd771
--- /dev/null
@@ -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 (file)
index 0000000..f40ae80
--- /dev/null
@@ -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 (file)
index 0000000..aef59ed
--- /dev/null
@@ -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 (file)
index 0000000..f25d371
--- /dev/null
@@ -0,0 +1,10 @@
+Invalid Code
+
+class Foo<G> {
+       static G bar () {
+               return null;
+       }
+}
+
+void main () {
+}
index fc8491594ae2b8cad4317b29ef1d80a5bc03876c..2794cd48eb312d6f29e68bfe24be4d41c5fc6b7a 100644 (file)
@@ -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;