Migrate language_2/type to NNBD.

Change-Id: I39fc62d6eab731f6defe2a1c11eb21c1ba7ed072
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151627
Auto-Submit: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
Robert Nystrom 2020-06-17 23:01:01 +00:00 committed by commit-bot@chromium.org
parent 2fe40ad6ed
commit 6e988a6d26
13 changed files with 535 additions and 0 deletions

View file

@ -0,0 +1,24 @@
// 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.
// Test that type aliases perform equality tests according to the
// underlying function type, not as if they were a distinct type
// for each type alias declaration.
import 'package:expect/expect.dart';
typedef F1 = void Function(int);
typedef F2 = void Function(int);
typedef void F3(int x);
typedef G1 = X Function<X>(X);
typedef G2 = X Function<X>(X);
typedef G3 = Y Function<Y>(Y);
main() {
Expect.equals(F1, F2); //# 01: ok
Expect.equals(F1, F3); //# 02: ok
Expect.equals(G1, G2); //# 03: ok
Expect.equals(G1, G3); //# 04: ok
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2014, 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 typechecks on const objects with typedefs work.
import "package:expect/expect.dart";
typedef String Int2String(int x);
class A {
final Int2String f;
const A(this.f);
}
int foo(String x) => 499;
const a = const A(foo); /*@compile-error=unspecified*/
main() {
a.f(499);
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2014, 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 typechecks on const objects with typedefs work.
import "package:expect/expect.dart";
typedef String Int2String(int x);
class A {
final Int2String f;
const A(this.f);
}
String foo(int x) => "str";
const a = const A(foo);
main() {
Expect.equals("str", a.f(499));
}

View file

@ -0,0 +1,19 @@
// Copyright (c) 2013, 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.
// Regression test for dart2js that used to remove the a B type check
// after an A type check, because it thought any subtype of A had to be B.
import "package:expect/expect.dart";
class A {}
class B extends A {}
main() {
var a = [new A(), new B()];
var b = a[0];
b = b as A;
Expect.throwsTypeError(() => b as B);
}

View file

@ -0,0 +1,43 @@
// TODO(multitest): This was automatically migrated from a multitest and may
// contain strange or dead code.
// Copyright (c) 2012, 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 the type checking when passing code into closure from inside a factory method
import "package:expect/expect.dart";
abstract class Foo<T> {
factory Foo.from() = Bar<T>.from;
}
class Bar<T> implements Foo<T> {
Bar() {}
factory Bar.from() {
var func = (T arg) {
T foo = arg;
bool isString = foo is String;
print(arg);
print(" String=$isString");
};
return new Bar<T>();
}
}
main() {
Foo<String> value1;
value1 = new Foo<String>.from();
bool gotError = false;
try {
Foo<int> value2 = new Foo<int>.from();
} on TypeError catch (e) {
gotError = true;
}
Expect.equals(false, gotError);
}

View file

@ -0,0 +1,43 @@
// Copyright (c) 2012, 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 the type checking when passing code into closure from inside a factory method
import "package:expect/expect.dart";
abstract class Foo<T> {
factory Foo.from() = Bar<T>.from;
}
class Bar<T> implements Foo<T> {
Bar() {}
factory Bar.from() {
var func = (T arg) {
T foo = arg;
bool isString = foo is String;
print(arg);
print(" String=$isString");
};
func("Hello World!");
// ^^^^^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
// [cfe] The argument type 'String' can't be assigned to the parameter type 'T'.
return new Bar<T>();
}
}
main() {
Foo<String> value1;
value1 = new Foo<String>.from();
bool gotError = false;
try {
Foo<int> value2 = new Foo<int>.from();
} on TypeError catch (e) {
gotError = true;
}
Expect.equals(false, gotError);
}

View file

@ -0,0 +1,82 @@
// 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.
// Test that the value of constant type literals are allowed as
// constant map keys and case expressions, and the value of non-constant type
// literals are not.
import "dart:collection" deferred as prefix;
main(args) {
testSwitch(args);
testMaps(args);
}
const Type numType = num;
Type argumentType<T>() => T;
void testSwitch<T extends MyType>(args) {
var types = [MyType, T, argumentType<MyType>(), argumentType<T>()];
for (int i = 0; i < types.length; i++) {
switch (types[i]) {
// Must be type literal or not override `==`.
case const MyType(): //# 01: compile-time error
// Must not be type variable.
case T: //# 02: compile-time error
// Must not be deferred type.
case prefix.HashSet: //# 03: compile-time error
// Constant type literals are valid.
case String:
throw "unreachable: String #$i";
case int:
throw "unreachable: int #$i";
case numType:
throw "unreachable: num #$i";
case MyType:
break;
default:
throw "unreachable: default #$i";
}
}
}
void testMaps<T extends MyType>(args) {
const map = {
// Must be type literal or not override `==`.
MyType(): 0, //# 04: compile-time error
// Must not be type variable.
T: 0, //# 05: compile-time error
// Must not be deferred.
prefix.HashSet: 0, //# 06: compile-time error
// Constant type literals are valid.
MyType: 0,
int: 1,
String: 2,
numType: 3,
};
if (map[MyType] != 0) throw "Map Error: ${MyType} as literal";
if (map[T] != 0) throw "Map Error: ${T} as type argument";
if (map[argumentType<MyType>()] != 0) {
throw "Map Error: ${argumentType<MyType>()} as type argument of literal";
}
if (map[argumentType<T>()] != 0) {
throw "Map Error: ${argumentType<T>()} as type argument of type variable";
}
if (map[num] != 3) throw "Map Error: ${num} -> ${map[num]}";
}
// An implementation of `Type` which overrides `==`,
// but is not the value of a constant type literal.
class MyType implements Type {
const MyType();
int get hashCode => 0;
bool operator ==(Object other) => identical(this, other);
}

View file

@ -0,0 +1,82 @@
// Copyright (c) 2013, 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.
// Regression test for dart2js, that used to generate bad code in
// checked mode. The pattern that lead to an error was:
//
// t1 = GeneratedAtUseSite instruction
// t2 = check(t1)
// t3 = check(t2)
// t4 = use(t3)
// t5 = use(t3)
// t6 = use(t2)
//
// The SSA variable allocator used to allocate the same variable for
// t5 and t2, because of a bogus optimization with check instructions.
expect(a, b) {
if (a != b) throw 'Failed';
}
var array = <dynamic>[
new SelectorGroup([
new Selector([new SimpleSelectorSequence(new ClassSelector())]),
new Selector([new SimpleSelectorSequence(new ClassSelector())]),
new Selector([new SimpleSelectorSequence(new ClassSelector())])
]),
new Object()
];
class RuleSet {
final SelectorGroup _selectorGroup;
RuleSet(this._selectorGroup);
SelectorGroup get selectorGroup => _selectorGroup;
}
class SelectorGroup {
List<Selector> _selectors;
SelectorGroup(this._selectors);
List<Selector> get selectors => _selectors;
}
class Selector {
final List<SimpleSelectorSequence> _simpleSelectorSequences;
Selector(this._simpleSelectorSequences);
List<SimpleSelectorSequence> get simpleSelectorSequences =>
_simpleSelectorSequences;
}
class SimpleSelectorSequence {
final SimpleSelector _selector;
SimpleSelectorSequence(this._selector);
get simpleSelector => _selector;
}
class SimpleSelector {}
class ClassSelector extends SimpleSelector {}
void testSelectorGroups() {
// Fetch the rule set from an array to trick the type inferrer.
var ruleset = new RuleSet(array[0]);
expect(ruleset.selectorGroup.selectors.length, 3);
var groupSelector0 = ruleset.selectorGroup.selectors[0];
var selector0 = groupSelector0.simpleSelectorSequences[0];
var simpleSelector0 = selector0.simpleSelector;
var groupSelector1 = ruleset.selectorGroup.selectors[1];
var selector1 = groupSelector1.simpleSelectorSequences[0];
var simpleSelector1 = selector1.simpleSelector;
expect(simpleSelector1 is ClassSelector, true);
var groupSelector2 = ruleset.selectorGroup.selectors[2];
}
main() {
testSelectorGroups();
// Trick the type inferrer.
new SimpleSelectorSequence(new SimpleSelector());
new SelectorGroup([]);
new Selector([]);
}

View file

@ -0,0 +1,45 @@
// Copyright (c) 2012, 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 various type errors produced by explicit casts don't invoke
// user-defined code during error reporting.
class NoToString {
toString() {
Expect.fail("should not be called");
return "";
}
}
/// Defeat optimizations of type checks.
dynamic wrap(e) {
if (new DateTime.now().year == 1980) return null;
return e;
}
bool assertionsEnabled = false;
void main() {
assert(assertionsEnabled = true);
dynamic noToString = NoToString();
Expect.throws<TypeError>(() {
wrap(noToString) as int; // Explicit cast should throw
}, (e) {
e.toString(); // Should not throw.
return true;
});
if (assertionsEnabled) {
Expect.throws<AssertionError>(() {
assert(wrap(false), noToString); // Assertion should throw
}, (e) {
e.toString(); // Should not throw.
return true;
});
}
}

View file

@ -0,0 +1,24 @@
// Copyright (c) 2012, 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";
foo() => 'bar';
main() {
var a = foo();
var b = 'c';
do {
b = a[2];
} while (b != 'r');
if (a is Comparable) {
// Re-assign "a" to disable the promotion to Comparable which would
// otherwise prohibit calling "+" on a.
a = a as dynamic;
a += a;
}
Expect.equals('barbar', a);
}

View file

@ -0,0 +1,63 @@
// Copyright (c) 2016, 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";
class A<T> {
A(this.x, T z);
A.make();
void f(T x) {}
static String g(String x) {
return x;
}
late T x;
}
class B extends A<int> {
B(int x, int z) : super(x, z);
B.make() : super.make();
void f(int x) {}
static int g(int x) {
return x;
}
}
class C {
C(this.x, int z);
void f(int x) {}
static int g(int x) {
return x;
}
int x = 0;
}
typedef void ToVoid<T>(T x);
typedef T Id<T>(T x);
void main() {
{
A<String> a = new A<String>("hello", "world");
Expect.isTrue(new A<String>.make() is! A<int>);
Expect.isTrue(new A.make() is A);
Expect.isTrue(a is! A<int>);
Expect.isTrue(a is A<String>);
Expect.isTrue(a.f is ToVoid<String>);
Expect.isTrue(A.g is Id<String>);
}
{
B b = new B(0, 1);
Expect.isTrue(new B.make() is B);
Expect.isTrue(new B.make() is A<int>);
Expect.isTrue(b is B);
Expect.isTrue(b.f is ToVoid<int>);
Expect.isTrue(B.g is Id<int>);
}
{
C c = new C(0, 1);
Expect.isTrue(c is C);
Expect.isTrue(c.f is ToVoid<int>);
Expect.isTrue(C.g is Id<int>);
}
}

View file

@ -0,0 +1,46 @@
// Copyright (c) 2012, 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 various type errors produced by implicit casts don't invoke
// user-defined code during error reporting.
class NoToString {
toString() {
Expect.fail("should not be called");
return "";
}
}
/// Defeat optimizations of type checks.
dynamic wrap(e) {
if (new DateTime.now().year == 1980) return null;
return e;
}
bool assertionsEnabled = false;
void main() {
assert(assertionsEnabled = true);
dynamic noToString = NoToString();
Expect.throws<TypeError>(() {
int x = wrap(noToString); // Implicit cast should throw
return x;
}, (e) {
e.toString(); // Should not throw.
return true;
});
if (assertionsEnabled) {
Expect.throws<TypeError>(() {
assert(wrap(noToString)); // Implicit cast should throw
}, (e) {
e.toString(); // Should not throw.
return true;
});
}
}

View file

@ -0,0 +1,20 @@
// Copyright (c) 2013, 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.
// Regression test for dart2js that used to consider that the
// intersection of [Comparable] and [num] is conflicting.
import "package:expect/expect.dart";
class A {
foo(a, Comparable b) => a == b;
bar(a, Comparable b) => b == a;
}
main() {
Expect.isFalse(new A().foo(1, 'foo'));
Expect.isTrue(new A().foo(1, 1));
Expect.isFalse(new A().bar(1, 'foo'));
Expect.isTrue(new A().bar(1, 1));
}