[vala/staging] vala: Include type-checks in preconditions of methods for type narrowing



commit e199f5621175c47a1b3c22a5c8c6337412df6fb9
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sat Feb 13 19:34:12 2021 +0100

    vala: Include type-checks in preconditions of methods for type narrowing
    
    See https://gitlab.gnome.org/GNOME/vala/issues/894

 tests/Makefile.am                                 |  1 +
 tests/objects/type-narrowing-by-precondition.vala | 19 +++++++++++++++++++
 vala/valamemberaccess.vala                        | 20 ++++++++++++++++++++
 3 files changed, 40 insertions(+)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 16820e66d..e7e7e9ced 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -497,6 +497,7 @@ TESTS = \
        objects/simple-generics-chainup.vala \
        objects/singleton.vala \
        objects/type-narrowing.vala \
+       objects/type-narrowing-by-precondition.vala \
        objects/type-narrowing-fallback.vala \
        objects/test-025.vala \
        objects/test-026.vala \
diff --git a/tests/objects/type-narrowing-by-precondition.vala 
b/tests/objects/type-narrowing-by-precondition.vala
new file mode 100644
index 000000000..5c6f42974
--- /dev/null
+++ b/tests/objects/type-narrowing-by-precondition.vala
@@ -0,0 +1,19 @@
+class Foo {
+       public void minim () requires (this is Bar) {
+               assert (this.i == 42);
+       }
+}
+
+class Bar : Foo {
+       public int i = 42;
+}
+
+void manam (Foo foo) requires (foo is Bar) {
+       assert (foo.i == 42);
+}
+
+void main () {
+       var bar = new Bar ();
+       manam (bar);
+       bar.minim ();
+}
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 06cf64ce4..735f1b79e 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -1130,6 +1130,7 @@ public class Vala.MemberAccess : Expression {
                bool is_negation = false;
                unowned CodeNode? parent = parent_node;
                unowned IfStatement? if_statement = null;
+               var scope_type_checks = new ArrayList<unowned TypeCheck> ();
                while (parent != null && !(parent is Method)) {
                        if (parent is TypeCheck) {
                                parent = null;
@@ -1140,6 +1141,14 @@ public class Vala.MemberAccess : Expression {
                                is_negation = if_statement.false_statement == parent;
                                break;
                        }
+                       if (parent.parent_node is Method) {
+                               foreach (Expression expr in ((Method) parent.parent_node).get_preconditions 
()) {
+                                       if (expr is TypeCheck) {
+                                               scope_type_checks.add ((TypeCheck) expr);
+                                       }
+                               }
+                               break;
+                       }
                        parent = parent.parent_node;
                }
 
@@ -1160,5 +1169,16 @@ public class Vala.MemberAccess : Expression {
                                }
                        }
                }
+               if (value_type.context_symbol == null) {
+                       foreach (TypeCheck type_check in scope_type_checks) {
+                               unowned TypeSymbol? narrowed_symnol = type_check.type_reference.type_symbol;
+                               if (variable == type_check.expression.symbol_reference) {
+                                       if (narrowed_symnol != value_type.type_symbol) {
+                                               value_type.context_symbol = narrowed_symnol;
+                                       }
+                                       value_type.nullable = false;
+                               }
+                       }
+               }
        }
 }


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