From 5805ecfa91bf876d87bf13610dda6b0040b1b36b Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Tue, 25 Jan 2022 21:54:09 +0100 Subject: [PATCH] WIP parser: Allow usage of dynamic on VarType --- tests/Makefile.am | 1 + tests/parser/var-type-dynamic.vala | 66 ++++++++++++++++++++++++++++++ vala/valaforeachstatement.vala | 8 ++++ vala/valalocalvariable.vala | 4 ++ vala/valaparser.vala | 14 +++++++ vala/valavartype.vala | 1 + 6 files changed, 94 insertions(+) create mode 100644 tests/parser/var-type-dynamic.vala diff --git a/tests/Makefile.am b/tests/Makefile.am index 0b9f71524..06bbb0049 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -972,6 +972,7 @@ TESTS = \ parser/using-ambiguous-reference.test \ parser/using-directive.vala \ parser/using-invalid-namespace.test \ + parser/var-type-dynamic.vala \ parser/var-type-nullable.vala \ parser/with-embedded.vala \ parser/with-empty.vala \ diff --git a/tests/parser/var-type-dynamic.vala b/tests/parser/var-type-dynamic.vala new file mode 100644 index 000000000..669e49608 --- /dev/null +++ b/tests/parser/var-type-dynamic.vala @@ -0,0 +1,66 @@ +class Foo : Object { + public string manam { get; set; default = "foo"; } +} + +void main () { + var foo = new Foo (); + var foo_list = new List (); + foo_list.prepend (foo); + + { + dynamic var bar = foo; + assert (bar.manam == "foo"); + } + { + dynamic unowned var bar = foo; + assert (bar.manam == "foo"); + } + { + dynamic var? bar = foo; + assert (bar.manam == "foo"); + } + { + dynamic unowned var? bar = foo; + assert (bar.manam == "foo"); + } + { + foreach (dynamic var bar in foo_list) { + assert (bar.manam == "foo"); + } + } + { + foreach (dynamic unowned var bar in foo_list) { + assert (bar.manam == "foo"); + } + } + { + foreach (dynamic var? bar in foo_list) { + assert (bar.manam == "foo"); + } + } + { + foreach (dynamic unowned var? bar in foo_list) { + assert (bar.manam == "foo"); + } + } + { + with (dynamic var bar = foo) { + assert (manam == "foo"); + } + } + { + with (dynamic unowned var bar = foo) { + assert (manam == "foo"); + } + } + { + with (dynamic var? bar = foo) { + assert (manam == "foo"); + } + } + { + with (dynamic unowned var? bar = foo) { + assert (manam == "foo"); + } + } +} diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala index f491c037f..a76938718 100644 --- a/vala/valaforeachstatement.vala +++ b/vala/valaforeachstatement.vala @@ -342,6 +342,7 @@ public class Vala.ForeachStatement : Block { // var type bool nullable = type_reference.nullable; bool value_owned = type_reference.value_owned; + bool is_dynamic = type_reference.nullable; type_reference = element_type.copy (); // FIXME Only follows "unowned var" otherwise inherit ownership of element-type if (!value_owned) { @@ -350,6 +351,9 @@ public class Vala.ForeachStatement : Block { if (nullable) { type_reference.nullable = true; } + if (is_dynamic) { + type_reference.is_dynamic = true; + } } else if (!element_type.compatible (type_reference)) { error = true; Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'", element_type.to_string (), type_reference.to_string ()); @@ -369,6 +373,7 @@ public class Vala.ForeachStatement : Block { // var type bool nullable = type_reference.nullable; bool value_owned = type_reference.value_owned; + bool is_dynamic = type_reference.nullable; type_reference = element_type.copy (); // FIXME Only follows "unowned var" otherwise inherit ownership of element-type if (!value_owned) { @@ -377,6 +382,9 @@ public class Vala.ForeachStatement : Block { if (nullable) { type_reference.nullable = true; } + if (is_dynamic) { + type_reference.is_dynamic = true; + } } else if (!element_type.compatible (type_reference)) { error = true; Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'", element_type.to_string (), type_reference.to_string ()); diff --git a/vala/valalocalvariable.vala b/vala/valalocalvariable.vala index e2a5c92c2..7bd67a391 100644 --- a/vala/valalocalvariable.vala +++ b/vala/valalocalvariable.vala @@ -156,12 +156,16 @@ public class Vala.LocalVariable : Variable { bool nullable = variable_type.nullable; bool value_owned = variable_type.value_owned; + bool is_dynamic = variable_type.nullable; variable_type = initializer.value_type.copy (); variable_type.value_owned = value_owned; variable_type.floating_reference = false; if (nullable) { variable_type.nullable = true; } + if (is_dynamic) { + variable_type.is_dynamic = true; + } initializer.target_type = variable_type; variable_type.check (context); diff --git a/vala/valaparser.vala b/vala/valaparser.vala index 1e84c8bfa..a8f083a82 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -2063,15 +2063,20 @@ public class Vala.Parser : CodeVisitor { void parse_local_variable_declarations (Block block) throws ParseError { var begin = get_location (); DataType variable_type; + bool is_dynamic = accept (TokenType.DYNAMIC); if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) { variable_type = new VarType (false); variable_type.nullable = accept (TokenType.INTERR); + variable_type.is_dynamic = is_dynamic; } else { rollback (begin); + is_dynamic = accept (TokenType.DYNAMIC); if (accept (TokenType.VAR)) { variable_type = new VarType (); variable_type.nullable = accept (TokenType.INTERR); + variable_type.is_dynamic = is_dynamic; } else { + rollback (begin); variable_type = parse_type (true, true); } } @@ -2375,15 +2380,20 @@ public class Vala.Parser : CodeVisitor { expect (TokenType.OPEN_PARENS); var var_or_type = get_location (); DataType type; + bool is_dynamic = accept (TokenType.DYNAMIC); if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) { type = new VarType (false); type.nullable = accept (TokenType.INTERR); + type.is_dynamic = is_dynamic; } else { rollback (var_or_type); + is_dynamic = accept (TokenType.DYNAMIC); if (accept (TokenType.VAR)) { type = new VarType (); type.nullable = accept (TokenType.INTERR); + type.is_dynamic = is_dynamic; } else { + rollback (var_or_type); type = parse_type (true, true); if (accept (TokenType.IN)) { Report.error (type.source_reference, "syntax error, expected `unowned var', `var' or type"); @@ -2551,14 +2561,18 @@ public class Vala.Parser : CodeVisitor { // Try "with (var identifier = expr)" rollback (expr_or_decl); DataType variable_type; + bool is_dynamic = accept (TokenType.DYNAMIC); if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) { variable_type = new VarType (false); variable_type.nullable = accept (TokenType.INTERR); + variable_type.is_dynamic = is_dynamic; } else { rollback (expr_or_decl); + is_dynamic = accept (TokenType.DYNAMIC); if (accept (TokenType.VAR)) { variable_type = new VarType (); variable_type.nullable = accept (TokenType.INTERR); + variable_type.is_dynamic = is_dynamic; } else { variable_type = parse_type (true, true); } diff --git a/vala/valavartype.vala b/vala/valavartype.vala index be97e1752..b31af255f 100644 --- a/vala/valavartype.vala +++ b/vala/valavartype.vala @@ -35,6 +35,7 @@ public class Vala.VarType : DataType { public override DataType copy () { var result = new VarType (value_owned); result.nullable = nullable; + result.is_dynamic = is_dynamic; return result; } } -- 2.47.2