[vala/wip/bug567269: 4/5] Allow multiple chain-up calls in the constructor
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/bug567269: 4/5] Allow multiple chain-up calls in the constructor
- Date: Mon, 19 Feb 2018 15:59:29 +0000 (UTC)
commit 0be1cb5dd15af8a18e44b1d32ac35bb8a768b90d
Author: Simon Werbeck <simon werbeck gmail com>
Date: Thu Nov 27 15:24:44 2014 +0100
Allow multiple chain-up calls in the constructor
This requires that the instance parameter is initialized at the end of
the constructor.
Another issue is the possibility of initializing 'this' more than once,
so I added a warning when this is the case.
https://bugzilla.gnome.org/show_bug.cgi?id=567269
tests/Makefile.am | 1 +
tests/chainup/class-multiple.vala | 49 +++++++++++++++++++++++++++++++++++++
vala/valaflowanalyzer.vala | 21 +++++++++++++--
vala/valamethodcall.vala | 4 ---
4 files changed, 68 insertions(+), 7 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7225478..718601f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -58,6 +58,7 @@ TESTS = \
chainup/base-struct-invalid.test \
chainup/class-base.vala \
chainup/class-base-foo.vala \
+ chainup/class-multiple.vala \
chainup/class-object.vala \
chainup/class-this.vala \
chainup/class-this-foo.vala \
diff --git a/tests/chainup/class-multiple.vala b/tests/chainup/class-multiple.vala
new file mode 100644
index 0000000..ae20b27
--- /dev/null
+++ b/tests/chainup/class-multiple.vala
@@ -0,0 +1,49 @@
+public class Foo {
+ public bool success;
+
+ Foo.first () {
+ success = true;
+ }
+
+ Foo.second () {
+ assert_not_reached ();
+ }
+
+ public Foo (bool cond) {
+ if (cond) {
+ this.first ();
+ } else {
+ this.second ();
+ }
+ }
+}
+
+public class Bar {
+ public bool success;
+
+ public Bar.first () {
+ success = true;
+ }
+
+ public Bar.second () {
+ assert_not_reached ();
+ }
+}
+
+public class Baz : Bar {
+ public Baz (bool cond) {
+ if (cond) {
+ base.first ();
+ } else {
+ base.second ();
+ }
+ }
+}
+
+void main () {
+ var foo = new Foo (true);
+ assert (foo.success);
+
+ var baz = new Baz (true);
+ assert (baz.success);
+}
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index ff0d9eb..d2de29c 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -207,6 +207,16 @@ public class Vala.FlowAnalyzer : CodeVisitor {
m.return_block.add_node (param_ma);
}
}
+
+ // ensure instance parameter is defined at end of creation method
+ if (m is CreationMethod) {
+ var cm = (CreationMethod) m;
+ if (cm.chain_up) {
+ var this_ma = new MemberAccess.simple ("this");
+ this_ma.symbol_reference = cm.this_parameter;
+ m.return_block.add_node (this_ma);
+ }
+ }
}
current_block = new BasicBlock ();
@@ -439,7 +449,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
void check_block_variables (BasicBlock block) {
foreach (PhiFunction phi in block.get_phi_functions ()) {
- Variable versioned_var = process_assignment (var_map, phi.original_variable);
+ Variable versioned_var = process_assignment (var_map, phi.original_variable,
phi.original_variable.parent_symbol);
phi_functions.set (versioned_var, phi);
}
@@ -474,7 +484,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
node.get_defined_variables (defined_variables);
foreach (Variable variable in defined_variables) {
- process_assignment (var_map, variable);
+ process_assignment (var_map, variable, node);
}
}
@@ -514,7 +524,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
}
}
- Variable process_assignment (Map<Symbol, List<Variable>> var_map, Variable var_symbol) {
+ Variable process_assignment (Map<Symbol, List<Variable>> var_map, Variable var_symbol, CodeNode
node_reference) {
var variable_stack = var_map.get (var_symbol);
if (variable_stack == null) {
variable_stack = new ArrayList<Variable> ();
@@ -527,6 +537,11 @@ public class Vala.FlowAnalyzer : CodeVisitor {
if (var_symbol is LocalVariable) {
versioned_var = new LocalVariable (var_symbol.variable_type.copy (), var_symbol.name,
null, var_symbol.source_reference);
} else {
+ if (var_symbol.name == "this" && var_symbol.parent_symbol is CreationMethod &&
((CreationMethod) var_symbol.parent_symbol).chain_up) {
+ if (variable_stack.size > 0) {
+ Report.warning (node_reference.source_reference, "possible
reassignment of `this'");
+ }
+ }
// parameter
versioned_var = new Parameter (var_symbol.name, var_symbol.variable_type.copy (),
var_symbol.source_reference);
}
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index 713b9bb..5c17ef0 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -238,10 +238,6 @@ public class Vala.MethodCall : Expression {
error = true;
Report.error (source_reference, "invocation not supported in this context");
return false;
- } else if (cm.chain_up) {
- error = true;
- Report.error (source_reference, "Multiple constructor calls in the same
constructor are not permitted");
- return false;
}
cm.chain_up = true;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]