Migrate language_2/implicit_creation to NNBD.

Change-Id: I4b287ab1f1160550682a6afb706f5985b9fb474d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148282
Auto-Submit: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Bob Nystrom <rnystrom@google.com>
This commit is contained in:
Robert Nystrom 2020-05-20 22:04:05 +00:00 committed by commit-bot@chromium.org
parent 819e82ee1d
commit 4c78bacd1d
24 changed files with 1896 additions and 5 deletions

View file

@ -196,7 +196,7 @@ class Expect {
*
* Uses `[]` for objects that are only identical to themselves.
*/
static List<List<int>> _findEquivalences(List<Object> objects) {
static List<List<int>> _findEquivalences(List<dynamic> objects) {
var equivalences = new List<List<int>>.generate(objects.length, (_) => []);
for (int i = 0; i < objects.length; i++) {
if (equivalences[i].isNotEmpty) continue;
@ -214,8 +214,8 @@ class Expect {
return equivalences;
}
static void _writeEquivalences(
List<Object> objects, List<List<int>> equivalences, StringBuffer buffer) {
static void _writeEquivalences(List<dynamic> objects,
List<List<int>> equivalences, StringBuffer buffer) {
var separator = "";
for (int i = 0; i < objects.length; i++) {
buffer.write(separator);
@ -233,7 +233,7 @@ class Expect {
}
}
static void allIdentical(List<Object> objects, [String reason = ""]) {
static void allIdentical(List<dynamic> objects, [String reason = ""]) {
if (objects.length <= 1) return;
String msg = _getMessage(reason);
var equivalences = _findEquivalences(objects);
@ -258,7 +258,7 @@ class Expect {
/**
* Checks that no two [objects] are `identical`.
*/
static void allDistinct(List<Object> objects, [String reason = ""]) {
static void allDistinct(List<dynamic> objects, [String reason = ""]) {
String msg = _getMessage(reason);
var equivalences = _findEquivalences(objects);

View file

@ -0,0 +1,52 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that constructor invocations are constant
// when evaluated in a const context.
class C<T> {
final T x;
const C.named(this.x);
// Static const.
static const staticConst = C<int>.named(42);
}
// Top-level const.
const topConst = C<int>.named(42);
main() {
const c0 = const C<int>.named(42); // Explicit const.
// RHS of const local variable.
const c1 = C<int>.named(42);
// Inside const expression.
var c2 = (const [C<int>.named(42)])[0]; // List element.
var c3 = (const {C<int>.named(42): 0}).keys.first; // Map key.
var c4 = (const {0: C<int>.named(42)}).values.first; // Map value.
var c5 = (const C.named(C<int>.named(42))).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case C<int>.named(42): break;
default: Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C.named(C<int>.named(42))
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,54 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that constructor invocations are constant
// when evaluated in a const context.
class C<T> {
final T x;
const C(this.x);
// Static const.
static const staticConst = C<int>(42);
}
// Top-level const.
const topConst = C<int>(42);
main() {
const c0 = const C<int>(42); // Explicit const.
// RHS of const local variable.
const c1 = C<int>(42);
// Inside const expression.
var c2 = (const [C<int>(42)])[0]; // List element.
var c3 = (const {C<int>(42): 0}).keys.first; // Map key.
var c4 = (const {0: C<int>(42)}).values.first; // Map value.
var c5 = (const C(C<int>(42))).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case C<int>(42):
break;
default:
Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C(C<int>(42))
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,54 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that constructor invocations are constant
// when evaluated in a const context.
class C {
final Object x;
const C.named(this.x);
// Static const.
static const staticConst = C.named(42);
}
// Top-level const.
const topConst = C.named(42);
main() {
const c0 = const C.named(42); // Explicit const.
// RHS of const local variable.
const c1 = C.named(42);
// Inside const expression.
var c2 = (const [C.named(42)])[0]; // List element.
var c3 = (const {C.named(42): 0}).keys.first; // Map key.
var c4 = (const {0: C.named(42)}).values.first; // Map value.
var c5 = (const C.named(C.named(42))).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case C.named(42):
break;
default:
Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C.named(C.named(42))
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,54 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that constructor invocations are constant
// when evaluated in a const context.
class C {
final Object x;
const C(this.x);
// Static const.
static const staticConst = C(42);
}
// Top-level const.
const topConst = C(42);
main() {
const c0 = const C(42); // Explicit const.
// RHS of const local variable.
const c1 = C(42);
// Inside const expression.
var c2 = (const [C(42)])[0]; // List element.
var c3 = (const {C(42): 0}).keys.first; // Map key.
var c4 = (const {0: C(42)}).values.first; // Map value.
var c5 = (const C(C(42))).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case C(42):
break;
default:
Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C(C(42))
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,63 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that list literals are constant when evaluated in a const context.
class C {
final Object x;
const C(this.x);
// Static const.
static const staticConst = <int>[42];
}
// Top-level const.
const topConst = <int>[42];
main() {
const c0 = const <int>[42]; // Explicit const.
// RHS of const local variable.
const c1 = <int>[42];
// Inside const expression.
var c2 = (const [
<int>[42]
])[0]; // List element.
var c3 = (const {
<int>[42]: 0
})
.keys
.first; // Map key.
var c4 = (const {
0: <int>[42]
})
.values
.first; // Map value.
var c5 = (const C(<int>[42])).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case <int>[42]:
break;
default:
Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C(<int>[42])
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,63 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that map literals are constant when evaluated in a const context.
class C {
final Object x;
const C(this.x);
// Static const.
static const staticConst = <int, int>{37: 87};
}
// Top-level const.
const topConst = <int, int>{37: 87};
main() {
const c0 = const <int, int>{37: 87}; // Explicit const.
// RHS of const local variable.
const c1 = <int, int>{37: 87};
// Inside const expression.
var c2 = (const [
<int, int>{37: 87}
])[0]; // List element.
var c3 = (const {
<int, int>{37: 87}: 0
})
.keys
.first; // Map key.
var c4 = (const {
0: <int, int>{37: 87}
})
.values
.first; // Map value.
var c5 = (const C(<int, int>{37: 87})).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case <int, int>{37: 87}:
break;
default:
Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C(<int, int>{37: 87})
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,78 @@
// Copyright (c) 2019, 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.
import "package:expect/expect.dart";
// Check places that are *not* supposed to be constant contexts,
// but which do require constant values, do not introduce an implicit const.
// Nested expressions still do.
// (Also acts as regression test for http:/dartbug.com/36533)
class C {
final v;
// Initializer of final field in class with const constructor.
// Can't use `const C()`, it's a cyclic constant dependency.
final i1 = []; //# 1: compile-time error
final i2 = const [];
final i3 = const [[]];
const C([this.v]);
// Initializer expression in generative const constructor.
const C.c1() : v = C(); //# 2: compile-time error
const C.c2() : v = const C();
const C.c3() : v = const C(C());
// Expression in redirecting generative const constuctor.
const C.r1() : this(C()); //# 3: compile-time error
const C.r2() : this(const C());
const C.r3() : this(const C(C()));
// Default value of positional optional parameter.
static List<C> foo([
p1 = C(), //# 4: compile-time error
p2 = const C(),
p3 = const C(C()),
]) =>
[p2, p3];
// Default value of named optional parameter.
static List<C> bar({
p1 = C(), //# 5: compile-time error
p2 = const C(),
p3 = const C(C()),
}) =>
[p2, p3];
}
void main() {
var c = const C();
var cc = const C(C());
// Check that const constructors can be invoked without `const`,
// creating new instances every time.
var nc1 = C();
var nc2 = C.c2();
var nc3 = C.c3();
var nc4 = C.r2();
var nc5 = C.r3();
Expect.allDistinct([nc1, nc2, nc3, nc4, nc5, c, cc]);
// Check that const invocations create identical objects.
Expect.identical(c, C.c2().v);
Expect.identical(cc, C.c3().v);
Expect.identical(c, C.r2().v);
Expect.identical(cc, C.r3().v);
Expect.identical(const [], C().i2);
Expect.identical(const [[]], C().i3);
Expect.identical(c, C.foo()[0]);
Expect.identical(cc, C.foo()[1]);
Expect.identical(c, C.bar()[0]);
Expect.identical(cc, C.bar()[1]);
}

View file

@ -0,0 +1,55 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_const_context_prefix_constructor_generic_named_test.dart"
as prefix;
// Test that constructor invocations are constant
// when evaluated in a const context.
class C<T> {
final T x;
const C.named(this.x);
// Static const.
static const staticConst = prefix.C<int>.named(42);
}
// Top-level const.
const topConst = prefix.C<int>.named(42);
main() {
const c0 = const prefix.C<int>.named(42); // Explicit const.
// RHS of const local variable.
const c1 = prefix.C<int>.named(42);
// Inside const expression.
var c2 = (const [prefix.C<int>.named(42)])[0]; // List element.
var c3 = (const {prefix.C<int>.named(42): 0}).keys.first; // Map key.
var c4 = (const {0: prefix.C<int>.named(42)}).values.first; // Map value.
var c5 = (const C.named(prefix.C<int>.named(42))).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case prefix.C<int>.named(42): break;
default: Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C.named(prefix.C<int>.named(42))
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,56 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_const_context_prefix_constructor_generic_test.dart" as prefix;
// Test that constructor invocations are constant
// when evaluated in a const context.
class C<T> {
final T x;
const C(this.x);
// Static const.
static const staticConst = prefix.C<int>(42);
}
// Top-level const.
const topConst = prefix.C<int>(42);
main() {
const c0 = const prefix.C<int>(42); // Explicit const.
// RHS of const local variable.
const c1 = prefix.C<int>(42);
// Inside const expression.
var c2 = (const [prefix.C<int>(42)])[0]; // List element.
var c3 = (const {prefix.C<int>(42): 0}).keys.first; // Map key.
var c4 = (const {0: prefix.C<int>(42)}).values.first; // Map value.
var c5 = (const C(prefix.C<int>(42))).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case prefix.C<int>(42):
break;
default:
Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C(prefix.C<int>(42))
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,56 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_const_context_prefix_constructor_named_test.dart" as prefix;
// Test that constructor invocations are constant
// when evaluated in a const context.
class C {
final Object x;
const C.named(this.x);
// Static const.
static const staticConst = prefix.C.named(42);
}
// Top-level const.
const topConst = prefix.C.named(42);
main() {
const c0 = const prefix.C.named(42); // Explicit const.
// RHS of const local variable.
const c1 = prefix.C.named(42);
// Inside const expression.
var c2 = (const [prefix.C.named(42)])[0]; // List element.
var c3 = (const {prefix.C.named(42): 0}).keys.first; // Map key.
var c4 = (const {0: prefix.C.named(42)}).values.first; // Map value.
var c5 = (const C.named(prefix.C.named(42))).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case prefix.C.named(42):
break;
default:
Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C.named(prefix.C.named(42))
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,56 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_const_context_prefix_constructor_test.dart" as prefix;
// Test that constructor invocations are constant
// when evaluated in a const context.
class C {
final Object x;
const C(this.x);
// Static const.
static const staticConst = prefix.C(42);
}
// Top-level const.
const topConst = prefix.C(42);
main() {
const c0 = const prefix.C(42); // Explicit const.
// RHS of const local variable.
const c1 = prefix.C(42);
// Inside const expression.
var c2 = (const [prefix.C(42)])[0]; // List element.
var c3 = (const {prefix.C(42): 0}).keys.first; // Map key.
var c4 = (const {0: prefix.C(42)}).values.first; // Map value.
var c5 = (const C(prefix.C(42))).x; // Constructor argument.
Expect.identical(c0, c1);
Expect.identical(c0, c2);
Expect.identical(c0, c3);
Expect.identical(c0, c4);
Expect.identical(c0, c5);
Expect.identical(c0, C.staticConst);
Expect.identical(c0, topConst);
// Switch case expression.
switch (c0) {
case prefix.C(42):
break;
default:
Expect.fail("Didn't match constant");
}
// Annotation argument.
// (Cannot check that it's const, just that it's accepted).
@C(prefix.C(42))
var foo = null;
foo; // avoid "unused" hints.
}

View file

@ -0,0 +1,123 @@
// Copyright (c) 2018, 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.
// Tests that const/new-insertion does the right thing for default values.
// A default-value expression does not introduce a const context.
main() {
foo();
bar();
baz();
qux();
C.foo();
C.bar();
new C().baz();
new C().qux();
new C.pos();
new C.nam();
const C.pos();
const C.nam();
}
// Default arguments must be const to be accepted
foo([x //
= const [C()] // //# o1: ok
= const {42: C()} // //# o2: ok
= const C(C()) // //# o3: ok
= [42] // //# e1: compile-time error
= {42: 42} // //# e2: compile-time error
= C([]) // //# e3: compile-time error
]) {
}
bar({x //
= const [C()] // //# o4: ok
= const {42: C()} // //# o5: ok
= const C(C()) // //# o6: ok
= [42] // //# e4: compile-time error
= {42: 42} // //# e5: compile-time error
= C([]) // //# e6: compile-time error
}) {
}
var baz = ([x
= const [C()] // //# o7: ok
= const {42: C()} // //# o8: ok
= const C(C()) // //# o9: ok
= [42] // //# e7: compile-time error
= {42: 42} // //# e8: compile-time error
= C([]) // //# e9: compile-time error
]) => 42;
var qux = ({x
= const [C()] // //# o10: ok
= const {42: C()} // //# o11: ok
= const C(C()) // //# o12: ok
= [42] // //# e10: compile-time error
= {42: 42} // //# e11: compile-time error
= C([]) // //# e12: compile-time error
}) => 42;
class C {
final x;
const C([this.x]);
const C.pos([this.x //
= const [C()] // //# o13: ok
= const {42: C()} // //# o14: ok
= const C(C()) // //# o15: ok
= [42] // //# e13: compile-time error
= {42: 42} // //# e14: compile-time error
= C([]) // //# e15: compile-time error
]);
const C.nam({this.x //
= const [C()] // //# o16: ok
= const {42: C()} // //# o17: ok
= const C(C()) // //# o18: ok
= [42] // //# e16: compile-time error
= {42: 42} // //# e17: compile-time error
= C([]) // //# e18: compile-time error
});
static foo([x //
= const [C()] // //# o19: ok
= const {42: C()} // //# o20: ok
= const C(C()) // //# o21: ok
= [42] // //# e19: compile-time error
= {42: 42} // //# e20: compile-time error
= C([]) // //# e21: compile-time error
]) {
}
static bar({x //
= const [C()] // //# o22: ok
= const {42: C()} // //# o23: ok
= const C(C()) // //# o24: ok
= [42] // //# e22: compile-time error
= {42: 42} // //# e23: compile-time error
= C([]) // //# e24: compile-time error
}) {
}
baz([x //
= const [C()] // //# o25: ok
= const {42: C()} // //# o26: ok
= const C(C()) // //# o27: ok
= [42] // //# e25: compile-time error
= {42: 42} // //# e26: compile-time error
= C([]) // //# e27: compile-time error
]) {
}
qux({x //
= const [C()] // //# o28: ok
= const {42: C()} // //# o29: ok
= const C(C()) // //# o30: ok
= [42] // //# e28: compile-time error
= {42: 42} // //# e29: compile-time error
= C([]) // //# e30: compile-time error
}) {
}
}

View file

@ -0,0 +1,69 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that an omitted `new` is allowed for a generic constructor invocation.
class C<T> {
final T x;
C(this.x); // Not const constructor.
const C.c(this.x); // Const constructor.
operator <(other) => this;
operator >(other) => other;
operator -() => this;
C<T> get self => this;
C<T> method() => self;
}
T id<T>(T x) => x;
main() {
const cc = const C<int>.c(42); // Canonicalized.
var x = 42; // Avoid constant parameter for constant constructor.
var c0 = new C<int>.c(x); // Original syntax.
// Uses of `C<int>.c(x)` in various contexts.
var c1 = C<int>.c(x);
var c2 = [C<int>.c(x)][0];
var c3 = {C<int>.c(x): 0}.keys.first;
var c4 = {0: C<int>.c(x)}.values.first;
var c5 = id(C<int>.c(x));
var c6 = C<int>.c(x).self;
var c7 = C<int>.c(x).method();
var c8 = C(C<int>.c(x)).x;
var c9 = -C<int>.c(x);
var c10 = C<int>.c(x) < 9;
var c11 = C(null) > C<int>.c(x);
var c12 = (c10 == c11) ? null : C<int>.c(x);
var c13 = C<int>.c(x)..method();
var c14;
try {
throw C<int>.c(x);
} catch (e) {
c14 = e;
}
switch (C<int>.c(x)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (C<int>.c(x); false; C<int>.c(x), C<int>.c(x)) {
Expect.fail("Unreachable");
}
var values =
[cc, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C<int>);
Expect.equals(42, (value as C<int>).x);
}
}

View file

@ -0,0 +1,85 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that an omitted `new` is allowed for a generic constructor invocation.
class C<T> {
final T x;
C(this.x); // Not const constructor.
const C.c(this.x); // Const constructor.
operator <(other) => this;
operator >(other) => other;
operator -() => this;
C<T> get self => this;
C<T> method() => self;
}
T id<T>(T x) => x;
main() {
const cc = const C<int>.c(42); // Canonicalized.
var c0 = new C<int>(42); // Original syntax.
// Uses of `C<int>(42)` in various contexts.
var c1 = C<int>(42);
var c2 = [C<int>(42)][0];
var c3 = {C<int>(42): 0}.keys.first;
var c4 = {0: C<int>(42)}.values.first;
var c5 = id(C<int>(42));
var c6 = C<int>(42).self;
var c7 = C<int>(42).method();
var c8 = C(C<int>(42)).x;
var c9 = -C<int>(42);
var c10 = C<int>(42) < 9;
var c11 = C(null) > C<int>(42);
var c12 = (c10 == c11) ? null : C<int>(42);
var c13 = C<int>(42)..method();
var c14;
try {
throw C<int>(42);
} catch (e) {
c14 = e;
}
switch (C<int>(42)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (C<int>(42); false; C<int>(42), C<int>(42)) {
Expect.fail("Unreachable");
}
var values = [
cc,
c0,
c1,
c2,
c3,
c4,
c5,
c6,
c7,
c8,
c9,
c10,
c11,
c12,
c13,
c14
];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C<int>);
Expect.equals(42, (value as C<int>).x);
}
}

View file

@ -0,0 +1,86 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that an omitted `new` is allowed for a non-generic class.
class C {
final Object? x;
C(this.x); // Not const constructor.
const C.c(this.x); // Const constructor.
operator <(other) => this;
operator >(other) => other;
operator -() => this;
C get self => this;
C method() => self;
}
T id<T>(T x) => x;
main() {
const cc = const C.c(42); // Canonicalized.
var x = 42; // Avoid constant parameter.
var c0 = new C.c(x); // Original syntax.
// Uses of `C.c(x)` in various contexts.
var c1 = C.c(x);
var c2 = [C.c(x)][0];
var c3 = {C.c(x): 0}.keys.first;
var c4 = {0: C.c(x)}.values.first;
var c5 = id(C.c(x));
var c6 = C.c(x).self;
var c7 = C.c(x).method();
var c8 = C(C.c(x)).x;
var c9 = -C.c(x);
var c10 = C.c(x) < 9;
var c11 = C(null) > C.c(x);
var c12 = (c10 == c11) ? null : C.c(x);
var c13 = C.c(x)..method();
var c14;
try {
throw C.c(x);
} catch (e) {
c14 = e;
}
Expect.isNotNull(c12);
switch (C.c(x)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (C.c(x); false; C.c(x), C.c(x)) {
Expect.fail("Unreachable");
}
var values = [
cc,
c0,
c1,
c2,
c3,
c4,
c5,
c6,
c7,
c8,
c9,
c10,
c11,
c12,
c13,
c14
];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C);
Expect.equals(42, (value as C).x);
}
}

View file

@ -0,0 +1,149 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Test that an omitted `new` is allowed for a non-generic class.
class C {
final Object? x;
C(this.x); // Not const constructor.
const C.c(this.x); // Const constructor.
operator <(other) => this;
operator >(other) => other;
operator -() => this;
C get self => this;
C method() => self;
}
T id<T>(T x) => x;
main() {
const cc = const C.c(42); // Canonicalized.
var c0 = new C(42); // Original syntax.
// Uses of `C(42)` in various contexts.
var c1 = C(42);
var c2 = [C(42)][0];
var c3 = {C(42): 0}.keys.first;
var c4 = {0: C(42)}.values.first;
var c5 = id(C(42));
var c6 = C(42).self;
var c7 = C(42).method();
var c8 = C(C(42)).x;
var c9 = -C(42);
var c10 = C(42) < 9;
var c11 = C(null) > C(42);
var c12 = (c10 == c11) ? null : C(42);
var c13 = C(42)..method();
var c14;
try {
throw C(42);
} catch (e) {
c14 = e;
}
switch (C(42)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (C(42); false; C(42), C(42)) {
Expect.fail("Unreachable");
}
var values = [
cc,
c0,
c1,
c2,
c3,
c4,
c5,
c6,
c7,
c8,
c9,
c10,
c11,
c12,
c13,
c14
];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C);
Expect.equals(42, (value as C).x);
}
}
void testNamed() {
const cc = const C.c(42); // Canonicalized.
var x = 42; // Avoid constant parameter.
var c0 = new C.c(x); // Original syntax.
// Uses of `C.c(x)` in various contexts.
var c1 = C.c(x);
var c2 = [C.c(x)][0];
var c3 = {C.c(x): 0}.keys.first;
var c4 = {0: C.c(x)}.values.first;
var c5 = id(C.c(x));
var c6 = C.c(x).self;
var c7 = C.c(x).method();
var c8 = C(C.c(x)).x;
var c9 = -C.c(x);
var c10 = C.c(x) < 9;
var c11 = C(null) > C.c(x);
var c12 = (c10 == c11) ? null : C.c(x);
var c13 = C.c(x)..method();
var c14;
try {
throw C.c(x);
} catch (e) {
c14 = e;
}
Expect.isNotNull(c12);
switch (C.c(x)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (C.c(x); false; C.c(x), C.c(x)) {
Expect.fail("Unreachable");
}
var values = [
cc,
c0,
c1,
c2,
c3,
c4,
c5,
c6,
c7,
c8,
c9,
c10,
c11,
c12,
c13,
c14
];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C);
Expect.equals(42, (value as C).x);
}
}

View file

@ -0,0 +1,228 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
// Tests that new-insertion always inserts `new` when not in const context,
// no matter what the arguments are.
// There is (currently) no automatic const insertion in non-const context.
//
// Not testing inference, so all type arguments are explicit.
main() {
var x = 42;
const cc42 = const C(42);
var c42 = cc42;
const clist = const <int>[37];
var list = clist;
const cmap = const <int, int>{19: 87};
var map = cmap;
{
// Constructor inside constructor.
var d42 = const D<int>(42);
const cd1 = const C(const D<int>(42));
const cd2 = C(D<int>(42)); // Const context.
var cd3 = C(D<int>(42)); // Non-constant context, so `new`.
var cd4 = C(D<int>(x)); // Non-constant context, so `new`.
var cd5 = C(d42); // Non-constant context, so `new`.
Expect.identical(cd1, cd2);
Expect.allDistinct([cd1, cd3, cd4, cd5]);
}
{
// List inside other constructor
const cl1 = const C(const <int>[37]);
const cl2 = C(clist); // Constant context.
const cl3 = C(const <int>[37]); // Constant context.
const cl4 = C(<int>[37]); // Constant context.
var cl5 = C(clist); // Non-constant context, so `new`.
var cl6 = C(const <int>[37]); // Non-constant context, so `new`.
var cl7 = C(list); // Non-constant context, so `new`.
var cl8 = C(<int>[37]); // Non-constant context, so `new`.
Expect.allIdentical([cl1, cl2, cl3, cl4]);
Expect.allDistinct([cl1, cl5, cl6, cl7, cl8]);
}
{
// Map inside other constructor.
const cm1 = C(cmap); // Constant context.
const cm2 = C(const <int, int>{19: 87}); // Constant context.
const cm3 = C(<int, int>{19: 87}); // Constant context.
var cm4 = C(cmap); // Non-constant context, so `new`.
var cm5 = C(const <int, int>{19: 87}); // Non-constant context, so `new`.
var cm6 = C(map); // Non-constant context, so `new`.
var cm7 = C(<int, int>{19: 87}); // Non-constant context, so `new`.
Expect.identical(cm1, cm2);
Expect.identical(cm1, cm3);
Expect.allDistinct([cm1, cm4, cm5, cm6, cm7]);
}
{
// Composite with more than one sub-expression.
const n1 = N(clist, cmap);
const n2 = N(const <int>[37], const <int, int>{19: 87});
const n3 = N(<int>[37], <int, int>{19: 87});
var n4 = N(const <int>[37], const <int, int>{19: 87});
var n5 = N(<int>[37], const <int, int>{19: 87});
var n6 = N(const <int>[37], <int, int>{19: 87});
var n7 = N(<int>[37], <int, int>{19: 87});
var n8 = N(clist, cmap);
var n9 = N(<int>[37], cmap);
var n10 = N(clist, <int, int>{19: 87});
var n11 = N(<int>[37], <int, int>{19: 87});
var n12 = N(list, cmap);
var n13 = N(clist, map);
var n14 = N(list, map);
Expect.identical(n1, n2);
Expect.identical(n1, n3);
Expect.allDistinct([n1, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14]);
Expect
.allIdentical([clist, n6.left, n10.left, n12.left, n13.left, n14.left]);
Expect.allDistinct([n5.left, n7.left, n9.left, n11.left]);
Expect.allIdentical(
[cmap, n5.right, n9.right, n12.right, n13.right, n14.right]);
Expect.allDistinct([n6.right, n7.right, n10.right, n11.right]);
const n20 = const N(const C(42), const <int>[37]);
const n21 = N(const C(42), const <int>[37]);
const n22 = N(C(42), const <int>[37]);
const n23 = N(C(42), clist);
const n24 = N(C(42), <int>[37]);
var n25 = N(const C(42), const <int>[37]);
var n26 = N(C(42), const <int>[37]);
var n27 = N(C(42), clist);
var n28 = N(C(42), <int>[37]);
var n29 = N(C(42), list);
var n30 = N(c42, clist);
var n31 = N(cc42, list);
Expect.allIdentical([n20, n21, n22, n23, n24]);
Expect.allDistinct([n20, n25, n26, n27, n28, n29, n30, n31]);
Expect.allDistinct([cc42, n28.left, n29.left]);
Expect.identical(cc42, n30.left);
Expect.identical(cc42, n31.left);
Expect.allIdentical([clist, n29.right, n30.right, n31.right]);
Expect.notIdentical(clist, n28.right);
}
{
// List literals.
const l20 = const [
const C(42),
const <int>[37]
];
const l21 = [
const C(42),
const <int>[37]
];
const l22 = [
C(42),
const <int>[37]
];
var l23 = const [C(42), clist];
const l24 = [
C(42),
<int>[37]
];
var l25 = [
const C(42),
const <int>[37]
];
var l26 = [
C(42),
const <int>[37]
];
var l27 = [C(42), clist];
var l28 = [
C(42),
<int>[37]
];
var l29 = [C(42), list];
var l30 = [c42, clist];
var l31 = [cc42, list];
Expect.allIdentical([l20, l21, l22, l23, l24]);
// List literals are never const unless in const context.
Expect.allDistinct([l20, l25, l26, l27, l28, l29, l30, l31]);
Expect.allIdentical([cc42, l25[0], l30[0], l31[0]]);
Expect.allDistinct([cc42, l26[0], l27[0], l28[0], l29[0]]);
Expect
.allIdentical([clist, l25[1], l26[1], l27[1], l29[1], l30[1], l31[1]]);
Expect.notIdentical(clist, l28[1]);
}
{
// Map literals.
const m20 = const <C, List<int>>{
const C(42): const <int>[37]
};
const m21 = {
const C(42): const <int>[37]
};
const m22 = {
C(42): const <int>[37]
};
var m23 = const {C(42): clist};
const m24 = {
C(42): <int>[37]
};
var m25 = {
const C(42): const <int>[37]
};
var m26 = {
C(42): const <int>[37]
};
var m27 = {C(42): clist};
var m28 = {
C(42): <int>[37]
};
var m29 = {C(42): list};
var m30 = {c42: clist};
var m31 = {cc42: list};
Expect.allIdentical([m20, m21, m22, m23, m24]);
// Map literals are never const unless in const context.
Expect.allDistinct([m20, m25, m26, m27, m28, m29, m30, m31]);
Expect.identical(cc42, m25.keys.first);
Expect.allDistinct(
[cc42, m26.keys.first, m27.keys.first, m28.keys.first, m29.keys.first]);
Expect.identical(cc42, m30.keys.first);
Expect.identical(cc42, m31.keys.first);
Expect.allIdentical([
clist,
m25.values.first,
m26.values.first,
m27.values.first,
m29.values.first,
m30.values.first,
m31.values.first
]);
Expect.notIdentical(clist, m28.values.first);
}
}
class C {
final Object x;
const C(this.x);
}
class D<T> {
final T x;
const D(this.x);
}
class N {
final Object left, right;
const N(this.left, this.right);
}

View file

@ -0,0 +1,115 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_new_or_const_generic_test.dart" as prefix;
// Test that const constructors with const arguments do not become const
// if not in a const context.
// This test uses a generic class cosntructor with no prefix,
// which requires new Dart 2 syntax.
main() {
// Various valid object creation expressions.
var x = 42; // non constant variable.
// Various valid object creation expressions of a generic constructor.
// (Requires inference to infer `<int>` for the invocations of `D`.)
var instances = <Object>[
new D(x),
new D(42),
const D(42),
D(x),
D(42),
new D.named(x),
new D.named(42),
const D.named(42),
D.named(x),
D.named(42),
new prefix.D(x),
new prefix.D(42),
const prefix.D(42),
prefix.D(x),
prefix.D(42),
new prefix.D.named(x),
new prefix.D.named(42),
const prefix.D.named(42),
prefix.D.named(x),
prefix.D.named(42),
new D<int>(x),
new D<int>(42),
const D<int>(42),
D<int>(x),
D<int>(42),
new D<int>.named(x),
new D<int>.named(42),
const D<int>.named(42),
D<int>.named(x),
D<int>.named(42),
new prefix.D<int>(x),
new prefix.D<int>(42),
const prefix.D<int>(42),
prefix.D<int>(x),
prefix.D<int>(42),
new prefix.D<int>.named(x),
new prefix.D<int>.named(42),
const prefix.D<int>.named(42),
prefix.D<int>.named(x),
prefix.D<int>.named(42),
];
const d42 = const D<int>(42);
for (var i = 0; i < instances.length; i++) {
var d = instances[i];
Expect.equals(d42, d);
if (i % 5 == 2) {
// The cases of D(42) without "new" are all constant.
Expect.identical(d42, d, "$i");
} else {
// The rest are not.
Expect.notIdentical(d42, d, "$i");
}
}
// Test instance creation with type parameters.
new G<int>().testWithInt();
}
class D<T> {
final T? x;
const D(this.x);
const D.named(this.x);
int get hashCode => x.hashCode;
bool operator ==(Object other) => other is D<Object> && x == other.x;
}
class G<T> {
// Tests creation of D<T> where T is a type variable.
void testWithInt() {
// Cannot create constants referencing T or x.
var instances = [
new D<T>(null),
D<T>(null),
new D<T>.named(null),
D<T>.named(null),
new prefix.D<T>(null),
prefix.D<T>(null),
new prefix.D<T>.named(null),
prefix.D<T>.named(null),
];
const dx = const D<int>(null);
Expect.allDistinct([dx]..addAll(instances));
for (var i = 0; i < instances.length; i++) {
var d = instances[i];
Expect.isTrue(d is D<T>);
Expect.isTrue(d is! D<Null>);
Expect.equals(dx, d, "$i");
}
}
}

View file

@ -0,0 +1,61 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_new_or_const_test.dart" as prefix;
// Test that const constructors with const arguments do not become const
// if not in a const context.
main() {
// Various valid object creation expressions.
var x = 42; // non constant variable.
var instances = <Object>[
new C(x),
new C(42),
const C(42),
C(x),
C(42),
new C.named(x),
new C.named(42),
const C.named(42),
C.named(x),
C.named(42),
new prefix.C(x),
new prefix.C(42),
const prefix.C(42),
prefix.C(x),
prefix.C(42),
new prefix.C.named(x),
new prefix.C.named(42),
const prefix.C.named(42),
prefix.C.named(x),
prefix.C.named(42),
];
// Test that the correct ones are constant, and the rest are not.
const c42 = const C(42); // Reference constant.
for (var i = 0; i < instances.length; i++) {
var c = instances[i];
Expect.equals(c42, c);
if (i % 5 == 2) {
Expect.identical(c42, c, "$i");
} else {
Expect.notIdentical(c42, c, "$i");
}
}
}
class C {
final Object x;
const C(this.x);
const C.named(this.x);
int get hashCode => x.hashCode;
bool operator ==(Object other) => other is C && x == other.x;
}

View file

@ -0,0 +1,71 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_new_prefix_constructor_generic_named_test.dart" as prefix;
// Test that an omitted `new` is allowed for a generic constructor invocation.
class C<T> {
final T x;
C(this.x); // Not const constructor.
const C.c(this.x); // Const constructor.
operator <(other) => this;
operator >(other) => other;
operator -() => this;
C<T> get self => this;
C<T> method() => self;
}
T id<T>(T x) => x;
main() {
const cc = const C<int>.c(42); // Canonicalized.
var x = 42; // Avoid constant parameter.
var c0 = new prefix.C<int>.c(x); // Original syntax.
// Uses of `prefix.C<int>.c(x)` in various contexts.
var c1 = prefix.C<int>.c(x);
var c2 = [prefix.C<int>.c(x)][0];
var c3 = {prefix.C<int>.c(x): 0}.keys.first;
var c4 = {0: prefix.C<int>.c(x)}.values.first;
var c5 = id(prefix.C<int>.c(x));
var c6 = prefix.C<int>.c(x).self;
var c7 = prefix.C<int>.c(x).method();
var c8 = C(prefix.C<int>.c(x)).x;
var c9 = -prefix.C<int>.c(x);
var c10 = prefix.C<int>.c(x) < 9;
var c11 = C(null) > prefix.C<int>.c(x);
var c12 = (c10 == c11) ? null : prefix.C<int>.c(x);
var c13 = prefix.C<int>.c(x)..method();
var c14;
try {
throw prefix.C<int>.c(x);
} catch (e) {
c14 = e;
}
switch (prefix.C<int>.c(x)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (prefix.C<int>.c(x); false; prefix.C<int>.c(x), prefix.C<int>.c(x)) {
Expect.fail("Unreachable");
}
var values =
[cc, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C<int>);
Expect.equals(42, (value as C<int>).x);
}
}

View file

@ -0,0 +1,87 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_new_prefix_constructor_generic_test.dart" as prefix;
// Test that an omitted `new` is allowed for a generic constructor invocation.
class C<T> {
final T x;
C(this.x); // Not const constructor.
const C.c(this.x); // Const constructor.
operator <(other) => this;
operator >(other) => other;
operator -() => this;
C<T> get self => this;
C<T> method() => self;
}
T id<T>(T x) => x;
main() {
const cc = const C<int>.c(42); // Canonicalized.
var c0 = new prefix.C<int>(42); // Original syntax.
// Uses of `prefix.C<int>(42)` in various contexts.
var c1 = prefix.C<int>(42);
var c2 = [prefix.C<int>(42)][0];
var c3 = {prefix.C<int>(42): 0}.keys.first;
var c4 = {0: prefix.C<int>(42)}.values.first;
var c5 = id(prefix.C<int>(42));
var c6 = prefix.C<int>(42).self;
var c7 = prefix.C<int>(42).method();
var c8 = C(prefix.C<int>(42)).x;
var c9 = -prefix.C<int>(42);
var c10 = prefix.C<int>(42) < 9;
var c11 = C(null) > prefix.C<int>(42);
var c12 = (c10 == c11) ? null : prefix.C<int>(42);
var c13 = prefix.C<int>(42)..method();
var c14;
try {
throw prefix.C<int>(42);
} catch (e) {
c14 = e;
}
switch (prefix.C<int>(42)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (prefix.C<int>(42); false; prefix.C<int>(42), prefix.C<int>(42)) {
Expect.fail("Unreachable");
}
var values = [
cc,
c0,
c1,
c2,
c3,
c4,
c5,
c6,
c7,
c8,
c9,
c10,
c11,
c12,
c13,
c14
];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C<int>);
Expect.equals(42, (value as C<int>).x);
}
}

View file

@ -0,0 +1,88 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_new_prefix_constructor_named_test.dart" as prefix;
// Test that an omitted `new` is allowed for a non-generic class.
class C {
final Object? x;
C(this.x); // Not const constructor.
const C.c(this.x); // Const constructor.
operator <(other) => this;
operator >(other) => other;
operator -() => this;
C get self => this;
C method() => self;
}
T id<T>(T x) => x;
main() {
const cc = const C.c(42); // Canonicalized.
var x = 42; // Avoid constant parameter.
var c0 = new prefix.C.c(x); // Original syntax.
// Uses of `prefix.C.c(x)` in various contexts.
var c1 = prefix.C.c(x);
var c2 = [prefix.C.c(x)][0];
var c3 = {prefix.C.c(x): 0}.keys.first;
var c4 = {0: prefix.C.c(x)}.values.first;
var c5 = id(prefix.C.c(x));
var c6 = prefix.C.c(x).self;
var c7 = prefix.C.c(x).method();
var c8 = C(prefix.C.c(x)).x;
var c9 = -prefix.C.c(x);
var c10 = prefix.C.c(x) < 9;
var c11 = C(null) > prefix.C.c(x);
var c12 = (c10 == c11) ? null : prefix.C.c(x);
var c13 = prefix.C.c(x)..method();
var c14;
try {
throw prefix.C.c(x);
} catch (e) {
c14 = e;
}
Expect.isNotNull(c12);
switch (prefix.C.c(x)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (prefix.C.c(x); false; prefix.C.c(x), prefix.C.c(x)) {
Expect.fail("Unreachable");
}
var values = [
cc,
c0,
c1,
c2,
c3,
c4,
c5,
c6,
c7,
c8,
c9,
c10,
c11,
c12,
c13,
c14
];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C);
Expect.equals(42, (value as C).x);
}
}

View file

@ -0,0 +1,88 @@
// Copyright (c) 2018, 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.
import "package:expect/expect.dart";
import "implicit_new_prefix_constructor_test.dart" as prefix;
// Test that an omitted `new` is allowed for a non-generic class.
class C {
final Object? x;
C(this.x); // Not const constructor.
const C.c(this.x); // Const constructor.
operator <(other) => this;
operator >(other) => other;
operator -() => this;
C get self => this;
C method() => self;
}
T id<T>(T x) => x;
main() {
const cc = const C.c(42); // Canonicalized.
var c0 = new prefix.C(42); // Original syntax.
// Uses of `prefix.C(42)` in various contexts.
var c1 = prefix.C(42);
var c2 = [prefix.C(42)][0];
var c3 = {prefix.C(42): 0}.keys.first;
var c4 = {0: prefix.C(42)}.values.first;
var c5 = id(prefix.C(42));
var c6 = prefix.C(42).self;
var c7 = prefix.C(42).method();
var c8 = C(prefix.C(42)).x;
var c9 = -prefix.C(42);
var c10 = prefix.C(42) < 9;
var c11 = C(null) > prefix.C(42);
var c12 = (c10 == c11) ? null : prefix.C(42);
var c13 = prefix.C(42)..method();
var c14;
try {
throw prefix.C(42);
} catch (e) {
c14 = e;
}
Expect.isNotNull(c12);
switch (prefix.C(42)) {
case cc:
Expect.fail("Should not be const");
break;
default:
// Success.
}
for (prefix.C(42); false; prefix.C(42), prefix.C(42)) {
Expect.fail("Unreachable");
}
var values = [
cc,
c0,
c1,
c2,
c3,
c4,
c5,
c6,
c7,
c8,
c9,
c10,
c11,
c12,
c13,
c14
];
Expect.allDistinct(values); // Non of them create constants.
for (var value in values) {
Expect.isTrue(value is C);
Expect.equals(42, (value as C).x);
}
}