blob: 35fd7012f84d78998b0ef47b1b6e6b0d6b4c6ee9 [file] [log] [blame]
// Copyright (c) 2021, 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.
/// @assertion We allow TypeName.new and TypeName<typeArgs>.new everywhere we
/// allow a reference to a named constructor. It instead refers to the unnamed
/// constructor. We allow tear-offs of the unnamed constructor by using .new and
/// then treating it as a named constructor tear-off. Examples:
///
/// class C<T> {
/// final T x;
/// const C.new(this.x); // Same as: `const C(this.x);`
/// C.other(T x) : this.new(x); // Same as: `: this(x)`
/// factory C.d(T x) = D<T>.new; // same as: `= D<T>;`
/// }
/// class D<T> extends C<T> {
/// const D(T x) : super.new(x); // Same as: `: super(x);`
/// }
/// void main() {
/// const C.new(0); // Same as: `const C(0);`. (Inferred `T` = `int`.)
/// const C<num>.new(0); // Same as: `const C<num>(0);`.
/// new C.new(0); // Same as `new C(0);`.
/// new C<num>.new(0); // Same as `new C<num>(0);`.
/// C.new(0); // Same as `C(0);`.
/// C<num>.new(0); // Same as `C<num>(0);`.
/// var f1 = C.new; // New tear-off, not expressible without `.new`.
/// var f2 = C<num>.new; // New tear-off, not expressible without `.new`.
/// }
///
/// @description Checks an example from the specification
/// @author sgrekhov@unipro.ru
// SharedOptions=--enable-experiment=constructor-tearoffs
import "../../Utils/expect.dart";
class C<T> {
final T x;
const C(this.x); // Same as: `const C(this.x);`
C.other(T x) : this.new(x); // Same as: `: this(x)`
factory C.d(T x) = D<T>.new; // same as: `= D<T>;`
}
class D<T> extends C<T> {
const D(T x) : super.new(x); // Same as: `: super(x);`
}
void main() {
const c1 = const C.new(42); // Same as: `const C(42);`. (Inferred `T` = `int`.)
Expect.equals(42, c1.x);
Expect.isFalse(c1.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c1.x);
const c2 = const C<num>(0); // Same as: `const C<num>(0);`.
Expect.equals(0, c2.x);
Expect.isTrue(c2.x is num);
Expect.isFalse(c2.x is String); // to check that x is not dynamic
Expect.runtimeIsType<num>(c2.x);
Expect.runtimeIsNotType<String>(c2.x);
var c3 = new C.new(0); // Same as `new C(0);`.
Expect.equals(0, c3.x);
Expect.isFalse(c3.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c3.x);
var c4 = new C<num>.new(0); // Same as `new C<num>(0);`.
Expect.equals(0, c4.x);
Expect.isFalse(c4.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c4.x);
var c5 = C.new(0); // Same as `C(0);`.
Expect.equals(0, c5.x);
Expect.isFalse(c5.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c5.x);
var c6 = C<num>.new(0); // Same as `C<num>(0);`.
Expect.equals(0, c6.x);
Expect.isFalse(c6.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c6.x);
var f1 = C.new; // New tear-off, not expressible without `.new`.
var c7 = f1(42);
Expect.equals(42, c7.x);
Expect.isFalse(c7.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c7.x);
var c8 = f1<num>(3.14);
Expect.equals(3.14, c8.x);
Expect.isFalse(c8.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c8.x);
var f2 = C<num>.new; // New tear-off, not expressible without `.new`.
var c9 = f2(3.14);
Expect.equals(3.14, c9.x);
Expect.isFalse(c9.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c9.x);
var c10 = C.other(42);
Expect.equals(42, c10.x);
Expect.isFalse(c10.x is String); // to check that x is not dynamic
Expect.runtimeIsNotType<String>(c10.x);
var c11 = C.d(42);
Expect.equals(42, c11.x);
Expect.isFalse(c11.x is String); // to check that x is not dynamic
Expect.isTrue(c11 is D);
Expect.runtimeIsNotType<String>(c11.x);
Expect.runtimeIsType<D>(c11);
}