Files
sdk/pkg/kernel/testcases/closures_initializers/initializers.dart
T
Samir Jindel a459f73fac Convert closures in all initializers, and share the context between them.
Summary:

Previously, we only handled `FieldInitializer` and `LocalInitializer`.

Now we handle all initializers.

Previously, we would create separate contexts for each initializers, which was
incorrect because it changes made to an argument from a closure within one
initializer would not be seen by a closure within another.

Now, we create the context in a `LocalInitializer` so all initializers will see
the same copy of the argument variables.

There is still an outstanding issue where variables introduced as local
initializers and later captured by closures in subsequent initializers are not
placed into the context. However, this will at least trigger an assert in the closure conversion pass.

Test Plan:

'closures_initializers/initializers.dart(.expect)' has been updated with very
simple test cases for super and redirecting initializers. The second bug
mentioned (captured local initializers) has not been reproduced yet.

BUG=
R=dmitryas@google.com

Review-Url: https://codereview.chromium.org/2981603002 .
2017-07-14 10:59:17 +02:00

53 lines
1.3 KiB
Dart

// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// The purpose of this test is to detect that closures in [LocalInitializer]s
// and [FieldInitializer]s are properly converted. This test assumes that
// [ArgumentExtractionForTesting] transformer was run before closure conversion.
// It should introduce one [LocalInitializer] for each argument passed to a
// field initializer for a field ending in "_li". If such argument contains a
// closure, it would appear in a [LocalInitializer]. The [FieldInitializer]
// example requires no such elaboration.
class X {}
// Closure in field initializer.
//
class A {
X foo;
A(X i) : foo = ((() => i)());
}
// Closure in super initializer.
//
class S extends A {
S(X i) : super((() => i)());
}
// Closure in local initializer.
//
class S2 {
X foo_li;
S2(X foo) : foo_li = (() => foo)();
}
// Closure in redirecting initializer.
//
class B {
X foo;
B.named(X foo) {}
B(X foo) : this.named((() => foo)());
}
main() {
A a = new A(new X());
a.foo; // To prevent dartanalyzer from marking [a] as unused.
B b = new B(new X());
b.foo;
S s = new S(new X());
s.foo;
S2 s2 = new S2(new X());
s2.foo_li;
}