[dart2js] Flip flag to defer class types.

Change-Id: Ia1f913a01f2be006158967b145db3ee34b297cfe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155660
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Joshua Litt 2020-08-17 20:25:09 +00:00 committed by commit-bot@chromium.org
parent 7d7c883890
commit eab26cd2bd
74 changed files with 417 additions and 248 deletions

View file

@ -19,7 +19,19 @@
* Introduces `Dart_FinalizableHandle`s. They do auto-delete, and the weakly
referred object cannot be accessed through them.
### Dart2JS
* Adds support for deferred loading of types seperately from classes. This
enables dart2js to make better optimization choices when deferred loading.
This work is necessary to address unsoundness in the deferred loading
algorithm. Currently, fixing this unsoundness would result in code bloat,
but loading types seperately from classes will allow us to fix the
unsoundness with only a minimal regression. To explicitly disable
deferred loading of types, pass `--no-defer-class-types`. See the original
post on the [unsoundness in the deferred loading algorithm][].
[#42982]: https://github.com/dart-lang/sdk/issues/42982
[unsoundness in the deferred loading algorithm]: https://github.com/dart-lang/sdk/blob/302ad7ab2cd2de936254850550aad128ae76bbb7/CHANGELOG.md#dart2js-3
### Tools

View file

@ -158,7 +158,7 @@ class CompilerOptions implements DiagnosticOptions {
bool reportInvalidInferredDeferredTypes = false;
/// Whether to defer load class types.
bool deferClassTypes = false; // default value.
bool deferClassTypes = true; // default value.
bool _deferClassTypes = false;
bool _noDeferClassTypes = false;

View file

@ -26,6 +26,8 @@ class B extends A { }
main() {
new A();
new B();
String c = '';
print(c);
}
""";
@ -34,6 +36,8 @@ class B extends A { }
class A { }
main() {
String c = '';
print(c);
new B();
new A();
}

View file

@ -18,6 +18,9 @@ void main() {
print('--test from kernel------------------------------------------------');
await deferredTest1();
await deferredTest2();
await deferredTest3();
await deferredTest4();
await deferredTest5();
});
}
@ -45,12 +48,75 @@ deferredTest2() async {
var closedWorld = compiler.backendClosedWorldForTesting;
var env = closedWorld.elementEnvironment;
var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
var outputUnitForClassType =
closedWorld.outputUnitData.outputUnitForClassType;
lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
dynamic shared = lookupLibrary("memory:shared.dart");
var a = env.lookupClass(shared, "A");
Expect.equals("OutputUnit(1, {import(def: deferred)})",
outputUnitForClass(a).toString());
Expect.equals("OutputUnit(1, {import(def: deferred)})",
outputUnitForClassType(a).toString());
}
deferredTest3() async {
CompilationResult result = await runCompiler(memorySourceFiles: TEST3);
Compiler compiler = result.compiler;
var closedWorld = compiler.backendClosedWorldForTesting;
var env = closedWorld.elementEnvironment;
var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
var outputUnitForClassType =
closedWorld.outputUnitData.outputUnitForClassType;
var mainOutputUnit = closedWorld.outputUnitData.mainOutputUnit;
lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
dynamic shared = lookupLibrary("memory:shared.dart");
var a = env.lookupClass(shared, "A");
Expect.equals(mainOutputUnit, outputUnitForClass(a));
Expect.equals(mainOutputUnit, outputUnitForClassType(a));
}
deferredTest4() async {
CompilationResult result = await runCompiler(memorySourceFiles: TEST4);
Compiler compiler = result.compiler;
var closedWorld = compiler.backendClosedWorldForTesting;
var env = closedWorld.elementEnvironment;
var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
var outputUnitForClassType =
closedWorld.outputUnitData.outputUnitForClassType;
var mainOutputUnit = closedWorld.outputUnitData.mainOutputUnit;
lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
dynamic shared = lookupLibrary("memory:shared.dart");
var a = env.lookupClass(shared, "A");
Expect.equals("OutputUnit(1, {import(def: deferred)})",
outputUnitForClass(a).toString());
Expect.equals(mainOutputUnit, outputUnitForClassType(a));
}
deferredTest5() async {
CompilationResult result = await runCompiler(memorySourceFiles: TEST5);
Compiler compiler = result.compiler;
var closedWorld = compiler.backendClosedWorldForTesting;
var env = closedWorld.elementEnvironment;
var outputUnitForClass = closedWorld.outputUnitData.outputUnitForClass;
var outputUnitForClassType =
closedWorld.outputUnitData.outputUnitForClassType;
lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
dynamic shared = lookupLibrary("memory:shared.dart");
var a = env.lookupClass(shared, "A");
Expect.equals(
"OutputUnit(1, {import(def2: deferred), import(def3: deferred)})",
outputUnitForClass(a).toString());
Expect.equals(
"OutputUnit(2, {import(def1: deferred), "
"import(def2: deferred), "
"import(def3: deferred)})",
outputUnitForClassType(a).toString());
}
// lib1 imports lib2 deferred. But mainlib never uses DeferredLibrary.
@ -81,8 +147,7 @@ void foo2() {}
""",
};
// main indirectly uses class A from shared. A should still be included in the
// main fragment.
// A's type should be in main.
const Map<String, String> TEST2 = const {
"main.dart": """
import 'def.dart' deferred as def;
@ -108,3 +173,94 @@ class B extends A {}
foo(B b) => null;
""",
};
// main directly uses class A from shared. A should be included in the
// main fragment.
const Map<String, String> TEST3 = const {
"main.dart": """
import 'def.dart' deferred as def;
import 'shared.dart';
main() {
print(A());
def.loadLibrary().then((_) {
def.toto();
});
}
""",
"def.dart": """
import 'shared.dart';
toto() { print(new A()); }
""",
"shared.dart": """
class A {}
class B extends A {}
""",
};
// main directly uses class A's type from shared. A's type but not class
// should be included in main.
const Map<String, String> TEST4 = const {
"main.dart": """
import 'def.dart' deferred as def;
import 'shared.dart';
main() {
print(5 is A);
def.loadLibrary().then((_) {
def.toto();
});
}
""",
"def.dart": """
import 'shared.dart';
toto() { print(new A()); }
""",
"shared.dart": """
class A {}
""",
};
// main doesn't directly use A's class or type, but does so indirectly.
const Map<String, String> TEST5 = const {
"main.dart": """
import 'def1.dart' deferred as def1;
import 'def2.dart' deferred as def2;
import 'def3.dart' deferred as def3;
main() {
def1.loadLibrary().then((_) {
def2.loadLibrary().then((_) {
def3.loadLibrary().then((_) {
def1.toto(null);
def2.toto();
def3.toto(null);
});
});
});
}
""",
"def1.dart": """
import 'shared.dart';
toto(x) => x is A;
""",
"def2.dart": """
import 'shared.dart';
toto() { print(A()); }
""",
"def3.dart": """
import 'shared.dart';
toto(x) {
print(new A());
return x is A;
}
""",
"shared.dart": """
class A {}
""",
};

View file

@ -8,7 +8,7 @@
library deferred_class_library;
/*class: MyClass:OutputUnit(1, {lib})*/
/*class: MyClass:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class MyClass {
/*member: MyClass.:OutputUnit(1, {lib})*/
const MyClass();

View file

@ -6,7 +6,7 @@
library deferred_constants1_lib3;
/*class: C:OutputUnit(main, {})*/
/*class: C:OutputUnit(main, {}), type=OutputUnit(main, {})*/
class C {
/*member: C.value:OutputUnit(main, {})*/
final value;

View file

@ -6,7 +6,7 @@
library deferred_constants2_lib;
/*class: Constant:OutputUnit(1, {lib})*/
/*class: Constant:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class Constant {
/*member: Constant.value:OutputUnit(1, {lib})*/
final value;

View file

@ -4,7 +4,7 @@
// @dart = 2.7
/*class: C:OutputUnit(main, {})*/
/*class: C:OutputUnit(main, {}), type=OutputUnit(main, {})*/
class C {
const C(this.x);

View file

@ -4,6 +4,6 @@
// @dart = 2.7
/*class: C3:OutputUnit(1, {lib1, lib2})*/
/*class: C3:OutputUnit(1, {lib1, lib2}), type=OutputUnit(1, {lib1, lib2})*/
/*member: C3.:OutputUnit(1, {lib1, lib2})*/
class C3 {}

View file

@ -6,6 +6,6 @@
import "deferred_overlapping_lib3.dart";
/*class: C1:OutputUnit(2, {lib1})*/
/*class: C1:OutputUnit(2, {lib1}), type=OutputUnit(2, {lib1})*/
/*member: C1.:OutputUnit(2, {lib1})*/
class C1 extends C3 {}

View file

@ -6,6 +6,6 @@
import "deferred_overlapping_lib3.dart";
/*class: C2:OutputUnit(3, {lib2})*/
/*class: C2:OutputUnit(3, {lib2}), type=OutputUnit(3, {lib2})*/
/*member: C2.:OutputUnit(3, {lib2})*/
class C2 extends C3 {}

View file

@ -4,7 +4,7 @@
// @dart = 2.7
/*class: M:OutputUnit(1, {lib})*/
/*class: M:none, type=OutputUnit(1, {lib})*/
class M {}
typedef dynamic FF({M b});

View file

@ -6,7 +6,7 @@
library deferred_typedef_lib1;
/*class: C:OutputUnit(1, {lib1})*/
/*class: C:OutputUnit(1, {lib1}), type=OutputUnit(1, {lib1})*/
class C {
/*member: C.a:OutputUnit(1, {lib1})*/
final a;

View file

@ -9,7 +9,7 @@ import 'lib2.dart' deferred as lib2;
const c = "string3";
/*class: C:OutputUnit(main, {})*/
/*class: C:OutputUnit(main, {}), type=OutputUnit(main, {})*/
class C {
/*member: C.p:OutputUnit(main, {})*/
final p;

View file

@ -15,7 +15,7 @@ const C2 = 1010;
const C2b = const C(1010);
/*class: D:null*/
/*class: D:none, type=none*/
class D {
static const C3 = "string2";

View file

@ -16,7 +16,7 @@ c() => print("123");
/*member: d:OutputUnit(1, {lib})*/
d() => print("123");
/*class: B:OutputUnit(1, {lib})*/
/*class: B:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class B {
/*member: B.:OutputUnit(1, {lib})*/
B() {
@ -24,14 +24,14 @@ class B {
}
}
/*class: B2:OutputUnit(1, {lib})*/
/*class: B2:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: B2.:OutputUnit(1, {lib})*/
class B2 extends B {
// No constructor creates a synthetic constructor that has an implicit
// super-call.
}
/*class: A:OutputUnit(1, {lib})*/
/*class: A:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class A {
/*member: A.:OutputUnit(1, {lib})*/
A() {
@ -39,17 +39,17 @@ class A {
}
}
/*class: A2:OutputUnit(1, {lib})*/
/*class: A2:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class A2 extends A {
// Implicit super call.
/*member: A2.:OutputUnit(1, {lib})*/
A2();
}
/*class: C1:OutputUnit(1, {lib})*/
/*class: C1:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class C1 {}
/*class: C2:OutputUnit(1, {lib})*/
/*class: C2:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class C2 {
/*member: C2.:OutputUnit(1, {lib})*/
C2() {
@ -57,33 +57,33 @@ class C2 {
}
}
/*class: C2p:null*/
/*class: C2p:none, type=none*/
class C2p {
C2() {
c();
}
}
/*class: C3:OutputUnit(1, {lib})*/
/*class: C3:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: C3.:OutputUnit(1, {lib})*/
class C3 extends C2 with C1 {
// Implicit redirecting "super" call via mixin.
}
/*class: E:OutputUnit(1, {lib})*/
/*class: E:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class E {}
/*class: F:OutputUnit(1, {lib})*/
/*class: F:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class F {}
/*class: G:OutputUnit(1, {lib})*/
/*class: G:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: G.:OutputUnit(1, {lib})*/
class G extends C3 with C1, E, F {}
/*class: D1:OutputUnit(1, {lib})*/
/*class: D1:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class D1 {}
/*class: D2:OutputUnit(1, {lib})*/
/*class: D2:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class D2 {
/*member: D2.:OutputUnit(1, {lib})*/
D2(x) {
@ -92,5 +92,5 @@ class D2 {
}
// Implicit redirecting "super" call with a parameter via mixin.
/*class: D3:OutputUnit(1, {lib})*/
/*class: D3:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
class D3 = D2 with D1;

View file

@ -4,10 +4,10 @@
// @dart = 2.7
/*class: A:OutputUnit(main, {})*/
/*class: A:OutputUnit(1, {lib1}), type=OutputUnit(main, {})*/
class A {
const A();
/*member: A.method:OutputUnit(main, {})*/
/*member: A.method:OutputUnit(1, {lib1})*/
method() {}
}

View file

@ -8,10 +8,7 @@ import 'dart:async';
import 'lib1.dart' deferred as lib1;
import 'lib2.dart' as lib2;
/*member: main:
OutputUnit(main, {}),
constants=[ConstructedConstant(A())=OutputUnit(1, {lib1})]
*/
/*member: main:OutputUnit(main, {}),constants=[ConstructedConstant(A())=OutputUnit(1, {lib1})]*/
main() async {
await lib1.loadLibrary();
lib1.field is FutureOr<lib2.A>;

View file

@ -6,8 +6,8 @@
// Test instantiation used only in a deferred library.
/*class: global#Instantiation:OutputUnit(1, {b})*/
/*class: global#Instantiation1:OutputUnit(1, {b})*/
/*class: global#Instantiation:OutputUnit(1, {b}), type=OutputUnit(1, {b})*/
/*class: global#Instantiation1:OutputUnit(1, {b}), type=OutputUnit(1, {b})*/
import 'lib1.dart' deferred as b;

View file

@ -7,9 +7,9 @@
// Test instantiations with different type argument count used only in two
// deferred libraries.
/*class: global#Instantiation:OutputUnit(2, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b})*/
/*class: global#Instantiation2:OutputUnit(3, {c})*/
/*class: global#Instantiation:OutputUnit(2, {b, c}), type=OutputUnit(2, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b}), type=OutputUnit(1, {b})*/
/*class: global#Instantiation2:OutputUnit(3, {c}), type=OutputUnit(3, {c})*/
import 'lib1.dart' deferred as b;
import 'lib2.dart' deferred as c;

View file

@ -7,8 +7,8 @@
// Test instantiations with the same type argument count used only in two
// deferred libraries.
/*class: global#Instantiation:OutputUnit(1, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b, c})*/
/*class: global#Instantiation:OutputUnit(1, {b, c}), type=OutputUnit(1, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b, c}), type=OutputUnit(1, {b, c})*/
import 'lib1.dart' deferred as b;
import 'lib2.dart' deferred as c;

View file

@ -6,8 +6,8 @@
// Test instantiation used only in a deferred library.
/*class: global#Instantiation:OutputUnit(1, {b})*/
/*class: global#Instantiation1:OutputUnit(1, {b})*/
/*class: global#Instantiation:OutputUnit(1, {b}), type=OutputUnit(1, {b})*/
/*class: global#Instantiation1:OutputUnit(1, {b}), type=OutputUnit(1, {b})*/
/*member: global#instantiate1:OutputUnit(1, {b})*/

View file

@ -9,10 +9,7 @@ T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
/*member: m:
OutputUnit(1, {b}),
constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]
*/
/*member: m:OutputUnit(1, {b}),constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]*/
m(int x, {G<int> f}) {
f ??= getFoo;
print(f(x));

View file

@ -7,9 +7,9 @@
// Test instantiations with different type argument count used only in two
// deferred libraries.
/*class: global#Instantiation:OutputUnit(2, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b})*/
/*class: global#Instantiation2:OutputUnit(3, {c})*/
/*class: global#Instantiation:OutputUnit(2, {b, c}), type=OutputUnit(2, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b}), type=OutputUnit(1, {b})*/
/*class: global#Instantiation2:OutputUnit(3, {c}), type=OutputUnit(3, {c})*/
/*member: global#instantiate1:OutputUnit(1, {b})*/
/*member: global#instantiate2:OutputUnit(3, {c})*/

View file

@ -7,8 +7,8 @@
// Test instantiations with the same type argument count used only in two
// deferred libraries.
/*class: global#Instantiation:OutputUnit(1, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b, c})*/
/*class: global#Instantiation:OutputUnit(1, {b, c}), type=OutputUnit(1, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b, c}), type=OutputUnit(1, {b, c})*/
/*member: global#instantiate1:OutputUnit(1, {b, c})*/

View file

@ -4,35 +4,35 @@
// @dart = 2.7
/*class: A:OutputUnit(1, {lib})*/
/*class: A:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: A.:OutputUnit(1, {lib})*/
class A {}
/*class: I:OutputUnit(1, {lib})*/
/*class: I:none, type=OutputUnit(1, {lib})*/
class I<T> {}
/*class: J:OutputUnit(1, {lib})*/
/*class: J:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: J.:OutputUnit(1, {lib})*/
class J<T> {}
// C needs to include "N", otherwise checking for `is I<A>` will likely cause
// problems
/*class: C:OutputUnit(1, {lib})*/
/*class: C:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: C.:OutputUnit(1, {lib})*/
class C extends A implements I<N> {}
/*class: C1:OutputUnit(1, {lib})*/
/*class: C1:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: C1.:OutputUnit(1, {lib})*/
class C1 extends J<M> implements A {}
/*class: C2:OutputUnit(1, {lib})*/
/*class: C2:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: C2.:OutputUnit(1, {lib})*/
class C2 extends J<M> implements I<N> {}
/*class: N:OutputUnit(1, {lib})*/
/*class: N:none, type=OutputUnit(1, {lib})*/
class N extends A {}
/*class: M:OutputUnit(1, {lib})*/
/*class: M:none, type=OutputUnit(1, {lib})*/
class M extends A {}
/*member: doCheck1:OutputUnit(1, {lib})*/

View file

@ -4,24 +4,24 @@
// @dart = 2.7
/*class: Foo:OutputUnit(1, {libA, libB, libC})*/
/*class: Foo:OutputUnit(1, {libB}), type=OutputUnit(3, {libA, libB, libC})*/
class Foo {
/*member: Foo.x:OutputUnit(1, {libA, libB, libC})*/
/*member: Foo.x:OutputUnit(1, {libB})*/
int x;
/*member: Foo.:OutputUnit(3, {libB})*/
/*member: Foo.:OutputUnit(1, {libB})*/
Foo() {
x = DateTime.now().millisecond;
}
/*member: Foo.method:OutputUnit(1, {libA, libB, libC})*/
/*member: Foo.method:OutputUnit(1, {libB})*/
int method() => x;
}
/*member: isFoo:OutputUnit(1, {libA, libB, libC})*/
/*member: isFoo:OutputUnit(3, {libA, libB, libC})*/
bool isFoo(o) {
return o is Foo;
}
/*member: callFooMethod:OutputUnit(3, {libB})*/
/*member: callFooMethod:OutputUnit(1, {libB})*/
int callFooMethod() {
return Foo().method();
}
@ -29,58 +29,58 @@ int callFooMethod() {
typedef int FunFoo(Foo a);
typedef int FunFunFoo(FunFoo b, int c);
/*member: isFunFunFoo:OutputUnit(1, {libA, libB, libC})*/
/*member: isFunFunFoo:OutputUnit(3, {libA, libB, libC})*/
bool isFunFunFoo(o) {
return o is FunFunFoo;
}
/*class: Aoo:OutputUnit(4, {libB, libC})*/
/*class: Aoo:none, type=OutputUnit(2, {libC})*/
class Aoo<T> {}
/*class: Boo:OutputUnit(4, {libB, libC})*/
/*class: Boo:OutputUnit(2, {libC}), type=OutputUnit(2, {libC})*/
class Boo<T> implements Aoo<T> {}
/*class: Coo:OutputUnit(4, {libB, libC})*/
/*member: Coo.:OutputUnit(6, {libC})*/
/*class: Coo:OutputUnit(2, {libC}), type=OutputUnit(2, {libC})*/
/*member: Coo.:OutputUnit(2, {libC})*/
class Coo<T> {}
/*class: Doo:OutputUnit(4, {libB, libC})*/
/*member: Doo.:OutputUnit(6, {libC})*/
/*class: Doo:OutputUnit(2, {libC}), type=OutputUnit(5, {libB, libC})*/
/*member: Doo.:OutputUnit(2, {libC})*/
class Doo<T> extends Coo<T> with Boo<T> {}
/*member: createDooFunFunFoo:OutputUnit(6, {libC})*/
/*member: createDooFunFunFoo:OutputUnit(2, {libC})*/
createDooFunFunFoo() => Doo<FunFunFoo>();
/*class: B:OutputUnit(2, {libA, libC})*/
/*member: B.:OutputUnit(6, {libC})*/
/*class: B:OutputUnit(2, {libC}), type=OutputUnit(2, {libC})*/
/*member: B.:OutputUnit(2, {libC})*/
class B {}
/*class: B2:OutputUnit(2, {libA, libC})*/
/*member: B2.:OutputUnit(6, {libC})*/
/*class: B2:OutputUnit(2, {libC}), type=OutputUnit(4, {libA, libC})*/
/*member: B2.:OutputUnit(2, {libC})*/
class B2 extends B {}
/*class: C1:OutputUnit(2, {libA, libC})*/
/*class: C1:OutputUnit(2, {libC}), type=OutputUnit(2, {libC})*/
class C1 {}
/*class: C2:OutputUnit(2, {libA, libC})*/
/*member: C2.:OutputUnit(6, {libC})*/
/*class: C2:OutputUnit(2, {libC}), type=OutputUnit(2, {libC})*/
/*member: C2.:OutputUnit(2, {libC})*/
class C2 {}
/*class: C3:OutputUnit(2, {libA, libC})*/
/*member: C3.:OutputUnit(6, {libC})*/
/*class: C3:OutputUnit(2, {libC}), type=OutputUnit(4, {libA, libC})*/
/*member: C3.:OutputUnit(2, {libC})*/
class C3 extends C2 with C1 {}
/*class: D1:OutputUnit(2, {libA, libC})*/
/*class: D1:OutputUnit(2, {libC}), type=OutputUnit(2, {libC})*/
class D1 {}
/*class: D2:OutputUnit(2, {libA, libC})*/
/*member: D2.:OutputUnit(6, {libC})*/
/*class: D2:OutputUnit(2, {libC}), type=OutputUnit(2, {libC})*/
/*member: D2.:OutputUnit(2, {libC})*/
class D2 {}
/*class: D3:OutputUnit(2, {libA, libC})*/
/*class: D3:OutputUnit(2, {libC}), type=OutputUnit(4, {libA, libC})*/
class D3 = D2 with D1;
/*member: isMega:OutputUnit(5, {libA})*/
/*member: isMega:OutputUnit(6, {libA})*/
bool isMega(o) {
return o is B2 || o is C3 || o is D3;
}

View file

@ -6,11 +6,11 @@
import 'lib.dart' as lib;
/*member: isFoo:OutputUnit(5, {libA})*/
/*member: isFoo:OutputUnit(6, {libA})*/
bool isFoo(o) => lib.isFoo(o);
/*member: isFunFunFoo:OutputUnit(5, {libA})*/
/*member: isFunFunFoo:OutputUnit(6, {libA})*/
bool isFunFunFoo(o) => lib.isFunFunFoo(o);
/*member: isMega:OutputUnit(5, {libA})*/
/*member: isMega:OutputUnit(6, {libA})*/
bool isMega(o) => lib.isMega(o);

View file

@ -6,14 +6,14 @@
import 'lib.dart' as lib;
/*member: callFooMethod:OutputUnit(3, {libB})*/
/*member: callFooMethod:OutputUnit(1, {libB})*/
int callFooMethod() => lib.callFooMethod();
/*member: isFoo:OutputUnit(3, {libB})*/
/*member: isFoo:OutputUnit(1, {libB})*/
bool isFoo(o) => lib.isFoo(o);
/*member: isFunFunFoo:OutputUnit(3, {libB})*/
/*member: isFunFunFoo:OutputUnit(1, {libB})*/
bool isFunFunFoo(o) => lib.isFunFunFoo(o);
/*member: isDooFunFunFoo:OutputUnit(3, {libB})*/
/*member: isDooFunFunFoo:OutputUnit(1, {libB})*/
bool isDooFunFunFoo(o) => o is lib.Doo<lib.FunFunFoo>;

View file

@ -6,20 +6,20 @@
import 'lib.dart' as lib;
/*member: isFoo:OutputUnit(6, {libC})*/
/*member: isFoo:OutputUnit(2, {libC})*/
bool isFoo(o) => lib.isFoo(o);
/*member: isFunFunFoo:OutputUnit(6, {libC})*/
/*member: isFunFunFoo:OutputUnit(2, {libC})*/
bool isFunFunFoo(o) => lib.isFunFunFoo(o);
/*member: createB2:OutputUnit(6, {libC})*/
/*member: createB2:OutputUnit(2, {libC})*/
createB2() => new lib.B2();
/*member: createC3:OutputUnit(6, {libC})*/
/*member: createC3:OutputUnit(2, {libC})*/
createC3() => new lib.C3();
/*member: createD3:OutputUnit(6, {libC})*/
/*member: createD3:OutputUnit(2, {libC})*/
createD3() => new lib.D3();
/*member: createDooFunFunFoo:OutputUnit(6, {libC})*/
/*member: createDooFunFunFoo:OutputUnit(2, {libC})*/
createDooFunFunFoo() => lib.createDooFunFunFoo();

View file

@ -8,7 +8,7 @@ import 'liba.dart' deferred as libA;
import 'libb.dart' deferred as libB;
import 'libc.dart' deferred as libC;
/*member: foo:OutputUnit(main, {}),constants=[FunctionConstant(callFooMethod)=OutputUnit(3, {libB}),FunctionConstant(createB2)=OutputUnit(6, {libC}),FunctionConstant(createC3)=OutputUnit(6, {libC}),FunctionConstant(createD3)=OutputUnit(6, {libC}),FunctionConstant(createDooFunFunFoo)=OutputUnit(6, {libC}),FunctionConstant(isDooFunFunFoo)=OutputUnit(3, {libB}),FunctionConstant(isFoo)=OutputUnit(3, {libB}),FunctionConstant(isFoo)=OutputUnit(5, {libA}),FunctionConstant(isFoo)=OutputUnit(6, {libC}),FunctionConstant(isFunFunFoo)=OutputUnit(3, {libB}),FunctionConstant(isFunFunFoo)=OutputUnit(5, {libA}),FunctionConstant(isFunFunFoo)=OutputUnit(6, {libC}),FunctionConstant(isMega)=OutputUnit(5, {libA})]*/
/*member: foo:OutputUnit(main, {}),constants=[FunctionConstant(callFooMethod)=OutputUnit(1, {libB}),FunctionConstant(createB2)=OutputUnit(2, {libC}),FunctionConstant(createC3)=OutputUnit(2, {libC}),FunctionConstant(createD3)=OutputUnit(2, {libC}),FunctionConstant(createDooFunFunFoo)=OutputUnit(2, {libC}),FunctionConstant(isDooFunFunFoo)=OutputUnit(1, {libB}),FunctionConstant(isFoo)=OutputUnit(1, {libB}),FunctionConstant(isFoo)=OutputUnit(2, {libC}),FunctionConstant(isFoo)=OutputUnit(6, {libA}),FunctionConstant(isFunFunFoo)=OutputUnit(1, {libB}),FunctionConstant(isFunFunFoo)=OutputUnit(2, {libC}),FunctionConstant(isFunFunFoo)=OutputUnit(6, {libA}),FunctionConstant(isMega)=OutputUnit(6, {libA})]*/
void foo() async {
await libA.loadLibrary();
await libB.loadLibrary();

View file

@ -6,6 +6,6 @@
import 'libc.dart';
/*class: C1:OutputUnit(1, {libb})*/
/*class: C1:OutputUnit(1, {libb}), type=OutputUnit(1, {libb})*/
/*member: C1.:OutputUnit(1, {libb})*/
class C1 extends C2 implements C3 {}

View file

@ -4,9 +4,9 @@
// @dart = 2.7
/*class: C2:OutputUnit(main, {})*/
/*class: C2:OutputUnit(1, {libb}), type=OutputUnit(main, {})*/
/*member: C2.:OutputUnit(1, {libb})*/
class C2 {}
/*class: C3:OutputUnit(main, {})*/
/*class: C3:none, type=OutputUnit(main, {})*/
class C3 {}

View file

@ -4,7 +4,7 @@
// @dart = 2.7
/*class: C:OutputUnit(1, {s1, s2})*/
/*class: C:OutputUnit(1, {s1, s2}), type=OutputUnit(1, {s1, s2})*/
class C {
const C();

View file

@ -6,7 +6,7 @@
library lib1;
/*class: ConstClass:OutputUnit(2, {lib1, lib2})*/
/*class: ConstClass:OutputUnit(2, {lib1, lib2}), type=OutputUnit(2, {lib1, lib2})*/
class ConstClass {
/*member: ConstClass.x:OutputUnit(2, {lib1, lib2})*/
final x;
@ -20,7 +20,7 @@ class ConstClass {
*/
var x = const ConstClass(const ConstClass(1));
/*class: C:OutputUnit(1, {lib1})*/
/*class: C:OutputUnit(1, {lib1}), type=OutputUnit(1, {lib1})*/
class C {
/*member: C.foo:OutputUnit(3, {lib2})*/
static foo() {
@ -38,7 +38,7 @@ class C {
}
}
/*class: C1:null*/
/*class: C1:none, type=none*/
class C1 {
/*member: C1.foo:
OutputUnit(3, {lib2}),
@ -48,7 +48,7 @@ class C1 {
var bar = const {};
}
/*class: C2:OutputUnit(1, {lib1})*/
/*class: C2:OutputUnit(1, {lib1}), type=OutputUnit(1, {lib1})*/
class C2 {
/*member: C2.foo:OutputUnit(3, {lib2})*/
static var foo = new Map<int, int>.from({1: 2});
@ -60,7 +60,7 @@ class C2 {
C2();
}
/*class: C3:OutputUnit(1, {lib1})*/
/*class: C3:OutputUnit(1, {lib1}), type=OutputUnit(1, {lib1})*/
class C3 {
/*member: C3.foo:
OutputUnit(3, {lib2}),
@ -78,7 +78,7 @@ class C3 {
C3();
}
/*class: C4:OutputUnit(1, {lib1})*/
/*class: C4:OutputUnit(1, {lib1}), type=OutputUnit(1, {lib1})*/
class C4 {
/*member: C4.foo:OutputUnit(3, {lib2})*/
static final foo = new Map<ConstClass, ConstClass>.from({x: x});
@ -90,7 +90,7 @@ class C4 {
C4();
}
/*class: C5:OutputUnit(1, {lib1})*/
/*class: C5:OutputUnit(1, {lib1}), type=OutputUnit(1, {lib1})*/
class C5 {
static const foo = const [
const {1: 3}

View file

@ -4,13 +4,13 @@
// @dart = 2.7
/*class: A:OutputUnit(main, {})*/
/*class: A:OutputUnit(1, {c}), type=OutputUnit(1, {c})*/
class A {
/*member: A.:OutputUnit(1, {c})*/
A();
}
/*class: B:OutputUnit(main, {})*/
/*class: B:none, type=OutputUnit(main, {})*/
class B extends A {}
/*member: createA:OutputUnit(1, {c})*/

View file

@ -6,12 +6,12 @@
import 'lib3.dart';
/*class: A:OutputUnit(1, {lib1})*/
/*class: A:OutputUnit(1, {lib1}), type=OutputUnit(1, {lib1})*/
class A<T> {
const A();
}
/*class: B:OutputUnit(1, {lib1})*/
/*class: B:none, type=OutputUnit(1, {lib1})*/
class B {}
const dynamic field1 = const A<B>();

View file

@ -4,12 +4,12 @@
// @dart = 2.7
/*class: C:OutputUnit(main, {})*/
/*class: C:OutputUnit(main, {}), type=OutputUnit(main, {})*/
class C<T> {
const C();
}
/*class: D:OutputUnit(main, {})*/
/*class: D:none, type=OutputUnit(main, {})*/
class D {}
const dynamic field = const C<D>();

View file

@ -4,12 +4,12 @@
// @dart = 2.7
/*class: E:OutputUnit(3, {lib3})*/
/*class: E:OutputUnit(2, {lib3}), type=OutputUnit(2, {lib3})*/
class E<T> {
const E();
}
/*class: F:OutputUnit(2, {lib1, lib3})*/
/*class: F:none, type=OutputUnit(3, {lib1, lib3})*/
class F {}
const dynamic field = const E<F>();

View file

@ -8,7 +8,7 @@ import 'lib1.dart' deferred as lib1;
import 'lib2.dart' as lib2;
import 'lib3.dart' deferred as lib3;
/*member: main:OutputUnit(main, {}),constants=[ConstructedConstant(A<B*>())=OutputUnit(1, {lib1}),ConstructedConstant(A<F*>())=OutputUnit(1, {lib1}),ConstructedConstant(C<D*>())=OutputUnit(main, {}),ConstructedConstant(E<F*>())=OutputUnit(3, {lib3})]*/
/*member: main:OutputUnit(main, {}),constants=[ConstructedConstant(A<B*>())=OutputUnit(1, {lib1}),ConstructedConstant(A<F*>())=OutputUnit(1, {lib1}),ConstructedConstant(C<D*>())=OutputUnit(main, {}),ConstructedConstant(E<F*>())=OutputUnit(2, {lib3})]*/
main() async {
await lib1.loadLibrary();
lib1.field1;

View file

@ -7,25 +7,25 @@
// All of these types are considered instantiated because we create an instance
// of [C].
/*class: A:OutputUnit(1, {lib})*/
/*class: A:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: A.:OutputUnit(1, {lib})*/
class A {}
/*class: Box:OutputUnit(1, {lib})*/
/*class: Box:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: Box.:OutputUnit(1, {lib})*/
class Box<T> {
/*member: Box.value:OutputUnit(1, {lib})*/
int value;
}
/*class: B:OutputUnit(1, {lib})*/
/*class: B:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: B.:OutputUnit(1, {lib})*/
class B<T> extends A {
/*member: B.box:OutputUnit(1, {lib})*/
final box = new Box<T>();
}
/*class: C:OutputUnit(1, {lib})*/
/*class: C:OutputUnit(1, {lib}), type=OutputUnit(1, {lib})*/
/*member: C.:OutputUnit(1, {lib})*/
class C extends B<N> {}
@ -35,5 +35,5 @@ class C extends B<N> {}
// to the main output unit. However, A is in the output unit of C so we fail
// when trying to finalize the declaration of N while loading the main output
// unit.
/*class: N:OutputUnit(1, {lib})*/
/*class: N:none, type=OutputUnit(1, {lib})*/
class N extends A {}

View file

@ -49,7 +49,7 @@ Map<String, Uri> importPrefixes = <String, Uri>{};
/// Create a consistent string representation of [OutputUnit]s for both
/// KImportEntities and ImportElements.
String outputUnitString(OutputUnit unit) {
if (unit == null) return 'null';
if (unit == null) return 'none';
StringBuffer sb = new StringBuffer();
bool first = true;
for (ImportEntity import in unit.importsForTesting) {
@ -139,8 +139,12 @@ class OutputUnitIrComputer extends IrDataExtractor<String> {
@override
String computeClassValue(Id id, ir.Class node) {
return outputUnitString(
_data.outputUnitForClassForTesting(_elementMap.getClass(node)));
var cls = _elementMap.getClass(node);
StringBuffer sb = new StringBuffer();
sb.write(outputUnitString(_data.outputUnitForClassForTesting(cls)));
sb.write(', type=');
sb.write(outputUnitString(_data.outputUnitForClassTypeForTesting(cls)));
return sb.toString();
}
@override

View file

@ -25,7 +25,7 @@ class E<T> extends B<T> {}
class F<T> extends B<List<T>>{}
class G {
call() {}
}
}
class H implements G {
call() {}
}
@ -108,7 +108,7 @@ main() {
elementEnvironment.forEachLocalClassMember(element, processMember);
List<String> expectedIsChecks = expectedIsChecksMap[element.name];
if (expectedIsChecks != null) {
if (!expectedIsChecks.isEmpty) {
Class cls = programLookup.getClass(element);
List<String> isChecks = cls.isChecks.map((m) => m.name.key).toList();
if (cls.functionTypeIndex != null) {

View file

@ -4,10 +4,10 @@
// @dart = 2.7
/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A:checkedTypeArgument,typeArgument*/
class A {}
/*class: B:checks=[],onlyForRti,typeArgument*/
/*class: B:typeArgument*/
class B {}
/*class: C:checkedInstance,checks=[],instance*/

View file

@ -6,7 +6,7 @@
import 'package:expect/expect.dart';
/*class: B:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: B:checkedInstance,typeArgument*/
class B {}
/*class: C:checks=[],instance*/

View file

@ -9,7 +9,7 @@ import 'package:expect/expect.dart';
/*class: A:checkedInstance,checks=[],instance*/
class A<T> {}
/*class: B:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B:checkedTypeArgument,typeArgument*/
class B {}
/*class: C:checks=[],instance*/
@ -21,10 +21,10 @@ class C {
method2<T>() => new A<T>();
}
/*class: D:checks=[],onlyForRti,typeArgument*/
/*class: D:typeArgument*/
class D extends B {}
/*class: E:checks=[],onlyForRti,typeArgument*/
/*class: E:typeArgument*/
class E {}
@pragma('dart2js:noInline')

View file

@ -4,7 +4,7 @@
// @dart = 2.7
/*class: global#Type:checks=[],instance,onlyForRti,typeLiteral*/
/*class: global#Type:instance,typeLiteral*/
import "package:expect/expect.dart";

View file

@ -4,12 +4,12 @@
// @dart = 2.7
/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: A:checkedTypeArgument,typeArgument*/
class A {}
/*spec.class: B:checkedInstance,checks=[$isA],onlyForRti,typeArgument*/
/*prod.class: B:checks=[$isA],onlyForRti,typeArgument*/
/*spec.class: B:checkedInstance,typeArgument*/
/*prod.class: B:typeArgument*/
class B implements A {}
/*class: C:checks=[],indirectInstance*/

View file

@ -7,11 +7,10 @@
// Test that we emit the relation between B and A even when B is only live
// as a type argument through the supertype of D.
/*spec.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A:checkedTypeArgument,typeArgument*/
class A {}
/*spec.class: B:checks=[$isA],onlyForRti,typeArgument*/
/*prod.class: B:checks=[],onlyForRti,typeArgument*/
/*class: B:typeArgument*/
class B implements A {}
/*spec.class: C:checkedInstance*/

View file

@ -18,10 +18,10 @@ main() {
test6();
}
/*class: B1:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B1:checkedTypeArgument,typeArgument*/
class B1<T> {}
/*class: C1:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: C1:checkedTypeArgument,typeArgument*/
class C1 extends B1<int> {}
@pragma('dart2js:noInline')
@ -34,10 +34,10 @@ test1() {
@pragma('dart2js:noInline')
_test1(f) => f is A<void Function(C1)>;
/*class: B2:checks=[],onlyForRti,typeArgument*/
/*class: B2:typeArgument*/
class B2<T> {}
/*class: C2:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: C2:checkedTypeArgument,typeArgument*/
class C2 extends B2<int> {}
@pragma('dart2js:noInline')
@ -50,10 +50,10 @@ test2() {
@pragma('dart2js:noInline')
_test2(f) => f is A<C2 Function()>;
/*class: B3:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B3:checkedTypeArgument,typeArgument*/
class B3<T> {}
/*class: C3:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: C3:checkedTypeArgument,typeArgument*/
class C3 extends B3<int> {}
@pragma('dart2js:noInline')
@ -66,10 +66,10 @@ test3() {
@pragma('dart2js:noInline')
_test3(f) => f is A<void Function(B3<int>)>;
/*class: B4:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B4:checkedTypeArgument,typeArgument*/
class B4<T> {}
/*class: C4:checks=[],onlyForRti,typeArgument*/
/*class: C4:typeArgument*/
class C4 extends B4<int> {}
@pragma('dart4js:noInline')
@ -82,10 +82,10 @@ test4() {
@pragma('dart4js:noInline')
_test4(f) => f is A<B4<int> Function()>;
/*class: B5:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B5:checkedTypeArgument,typeArgument*/
class B5<T> {}
/*class: C5:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: C5:checkedTypeArgument,typeArgument*/
class C5 extends B5<int> {}
@pragma('dart2js:noInline')
@ -98,10 +98,10 @@ test5() {
@pragma('dart2js:noInline')
_test5(f) => f is A<void Function(C5 Function())>;
/*class: B6:checks=[],onlyForRti,typeArgument*/
/*class: B6:typeArgument*/
class B6<T> {}
/*class: C6:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: C6:checkedTypeArgument,typeArgument*/
class C6 extends B6<int> {}
@pragma('dart2js:noInline')

View file

@ -6,15 +6,15 @@
import 'dart:async';
/*class: global#Future:checks=[],onlyForRti,typeArgument*/
/*class: global#Future:typeArgument*/
/*class: A:checkedInstance,checks=[],instance*/
class A<T> {}
/*class: B:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B:checkedTypeArgument,typeArgument*/
class B {}
/*class: C:checks=[],onlyForRti,typeArgument*/
/*class: C:typeArgument*/
class C {}
@pragma('dart2js:noInline')

View file

@ -18,10 +18,10 @@ class A<T> {
/*class: B:checkedInstance,checkedTypeArgument,checks=[],instance,typeArgument*/
class B<T> {}
/*class: C:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: C:checkedInstance,checkedTypeArgument,typeArgument*/
class C {}
/*class: D:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: D:checkedInstance,checkedTypeArgument,typeArgument*/
class D {}
main() {

View file

@ -20,7 +20,7 @@ class B {}
// TODO(johnniwinther): Do we need the implied `checkedTypeArgument` from
// the `Future<C>` test in `A.m`?
/*class: C:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: C:checkedInstance,typeArgument*/
class C {}
/*class: FutureMock:checks=[$isFuture],instance*/

View file

@ -18,10 +18,10 @@ class A<T> {
/*class: B:checkedInstance,checkedTypeArgument,checks=[],instance,typeArgument*/
class B<T> {}
/*class: C:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: C:checkedInstance,typeArgument*/
class C {}
/*class: D:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: D:checkedInstance,typeArgument*/
class D {}
main() {

View file

@ -7,15 +7,15 @@
import 'dart:async';
import 'package:expect/expect.dart';
/*class: global#Future:checks=[],onlyForRti,typeArgument*/
/*class: global#Future:typeArgument*/
/*class: A:checkedInstance,checks=[],instance*/
class A<T> {}
/*class: B:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B:checkedTypeArgument,typeArgument*/
class B {}
/*class: C:checks=[],onlyForRti,typeArgument*/
/*class: C:typeArgument*/
class C {}
@pragma('dart2js:noInline')

View file

@ -12,7 +12,7 @@ class A<T> {
}
}
/*class: BB:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: BB:checkedInstance,typeArgument*/
class BB {}
/*class: B:checks=[$isBB],instance*/

View file

@ -8,7 +8,7 @@
library generic_methods_dynamic_test;
/*spec.class: A:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*spec.class: A:checkedInstance,typeArgument*/
class A {}
/*spec.class: B:checks=[],instance*/

View file

@ -4,10 +4,10 @@
// @dart = 2.7
/*class: A:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: A:checkedInstance,typeArgument*/
abstract class A {}
/*class: B:checks=[$isA],onlyForRti,typeArgument*/
/*class: B:typeArgument*/
class B implements A {}
/*class: C:checkedInstance,checks=[],instance,typeArgument*/

View file

@ -7,15 +7,15 @@
@JS()
library foo;
/*class: global#JavaScriptObject:checks=[$isA],onlyForRti*/
/*class: global#JavaScriptObject:*/
import 'package:expect/expect.dart';
import 'package:js/js.dart';
@JS()
@anonymous
/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: A:checkedTypeArgument,typeArgument*/
class A<T> {
external factory A();
}

View file

@ -9,12 +9,12 @@
/*class: global#Iterable:checkedInstance*/
/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: A:checkedTypeArgument,typeArgument*/
class A {}
/*spec.class: B:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*prod.class: B:checks=[],onlyForRti,typeArgument*/
/*spec.class: B:checkedInstance,typeArgument*/
/*prod.class: B:typeArgument*/
class B {}
@pragma('dart2js:noInline')

View file

@ -9,7 +9,7 @@
/*class: global#LinkedHashMap:*/
/*class: global#JsLinkedHashMap:checks=[],instance*/
/*spec.class: global#double:checkedInstance,checks=[],instance,onlyForRti,typeArgument*/
/*spec.class: global#double:checkedInstance,instance,typeArgument*/
/*class: global#JSDouble:checks=[],instance*/

View file

@ -12,19 +12,19 @@ import "package:expect/expect.dart";
// A mixin with multiple super-types and implemented types.
/*class: A:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: A:checkedInstance,typeArgument*/
class A {}
/*class: B:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: B:checkedInstance,typeArgument*/
class B {}
/*class: I:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: I:checkedInstance,typeArgument*/
class I {}
/*class: J:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: J:checkedInstance,typeArgument*/
class J {}
/*class: M1:checkedInstance,checks=[$isA,$isB,$isI,$isJ],onlyForRti,typeArgument*/
/*class: M1:checkedInstance,typeArgument*/
mixin M1 on A, B implements I, J {}
/*class: M2:checkedInstance,checks=[$isA,$isB,$isI,$isJ],typeArgument*/
@ -42,13 +42,13 @@ class M5 implements A, B, I, J {}
/*class: C:checkedInstance,checks=[$isA,$isB],indirectInstance,typeArgument*/
class C implements A, B {}
/*class: D1:checkedInstance,checks=[$isI,$isJ,$isM1],onlyForRti,typeArgument*/
/*class: D1:checkedInstance,typeArgument*/
class D1 = C with M1;
/*class: D2:checkedInstance,checks=[$isI,$isJ],instance,typeArgument*/
class D2 = C with M2;
/*class: D3:checkedInstance,checks=[$isI,$isJ,$isM3],onlyForRti,typeArgument*/
/*class: D3:checkedInstance,typeArgument*/
class D3 = C with M3;
/*class: D4:checkedInstance,checks=[$isI,$isJ],instance,typeArgument*/
@ -61,25 +61,25 @@ class D5 extends C with M5 {}
class E5 extends D5 {}
// Same, with generics.
/*class: GA:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: GA:checkedInstance,typeArgument*/
class GA<T> {}
/*class: GB:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: GB:checkedInstance,typeArgument*/
class GB<T> {}
/*class: GI:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: GI:checkedInstance,typeArgument*/
class GI<T> {}
/*class: GJ:checkedInstance,checks=[],onlyForRti,typeArgument*/
/*class: GJ:checkedInstance,typeArgument*/
class GJ<T> {}
/*class: GM:checkedInstance,checks=[$isGA,$isGB,$isGI,$isGJ],onlyForRti,typeArgument*/
/*class: GM:checkedInstance,typeArgument*/
mixin GM<T> on GA<T>, GB<List<T>> implements GI<Iterable<T>>, GJ<Set<T>> {}
/*class: GC:checkedInstance,checks=[$isGA,$isGB],onlyForRti,typeArgument*/
/*class: GC:checkedInstance,typeArgument*/
class GC<T> implements GA<T>, GB<List<T>> {}
/*class: GD:checkedInstance,checks=[$isGI,$isGJ,$isGM],onlyForRti,typeArgument*/
/*class: GD:checkedInstance,typeArgument*/
class GD<T> = GC<T> with GM<T>;
@pragma('dart2js:noInline')

View file

@ -6,22 +6,22 @@
import 'package:expect/expect.dart' show Expect;
/*class: A:checks=[],onlyForRti,typeArgument*/
/*class: A:typeArgument*/
class A {}
/*class: B:checks=[],onlyForRti,typeArgument*/
/*class: B:typeArgument*/
class B {}
/*class: C:checks=[],onlyForRti,typeArgument*/
/*class: C:typeArgument*/
class C {}
/*class: D:checks=[],onlyForRti,typeArgument*/
/*class: D:typeArgument*/
class D {}
/*class: E:checks=[],onlyForRti,typeArgument*/
/*class: E:typeArgument*/
class E {}
/*class: F:checks=[],onlyForRti,typeArgument*/
/*class: F:typeArgument*/
class F {}
/*class: M1:checks=[]*/

View file

@ -24,10 +24,10 @@ class Removed {} // allocated but optimized out of program
/*class: DeferredAndRemoved:checks=[],onlyForConstructor*/
class DeferredAndRemoved {} // allocated after first check and removed
/*class: UsedAsTypeParameter:checks=[],onlyForRti,typeArgument*/
/*class: UsedAsTypeParameter:typeArgument*/
class UsedAsTypeParameter {} // only used as a type parameter
/*class: UsedAsTestedTypeParameter:checks=[],onlyForRti,typeArgument*/
/*class: UsedAsTestedTypeParameter:typeArgument*/
class UsedAsTestedTypeParameter {} // only used as a type parameter
/*class: Check:checks=[],instance*/

View file

@ -14,7 +14,7 @@ class Class<T> {
Type get type => T;
}
/*class: A:checks=[],onlyForRti,typeArgument*/
/*class: A:typeArgument*/
class A {}
@pragma('dart2js:noInline')

View file

@ -7,7 +7,7 @@
/*class: A:checks=[],instance*/
class A<T> {}
/*class: B:checks=[],onlyForRti,typeArgument*/
/*class: B:typeArgument*/
class B<T> {}
main() {

View file

@ -8,32 +8,32 @@
import 'package:expect/expect.dart';
/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: A:checkedTypeArgument,typeArgument*/
class A {}
/*spec.class: A1:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: A1:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A1:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: A1:checkedTypeArgument,typeArgument*/
class A1 {}
/*spec.class: A2:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: A2:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A2:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: A2:checkedTypeArgument,typeArgument*/
class A2 {}
/*spec.class: B:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2],onlyForRti,typeArgument*/
/*prod.class: B:checkedTypeArgument,checks=[$isA,$isA1,$isA2],onlyForRti,typeArgument*/
/*spec.class: B:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: B:checkedTypeArgument,typeArgument*/
class B implements A, A1, A2 {}
/*spec.class: C:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],onlyForRti,typeArgument*/
/*prod.class: C:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],onlyForRti,typeArgument*/
/*spec.class: C:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: C:checkedTypeArgument,typeArgument*/
class C implements B {}
/*spec.class: D:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],onlyForRti,typeArgument*/
/*prod.class: D:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],onlyForRti,typeArgument*/
/*spec.class: D:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: D:checkedTypeArgument,typeArgument*/
class D implements C {}
/*spec.class: G:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: G:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: G:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: G:checkedTypeArgument,typeArgument*/
class G<T, S, U, W> {}
typedef classesFunc({A a, B b, C c, D d});

View file

@ -4,7 +4,7 @@
// @dart = 2.7
/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A:checkedTypeArgument,typeArgument*/
class A<T> {}
/*class: B:checkedInstance,checks=[],indirectInstance*/

View file

@ -4,7 +4,7 @@
// @dart = 2.7
/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A:checkedTypeArgument,typeArgument*/
class A<T> {}
/*class: B:checkedInstance*/

View file

@ -4,7 +4,7 @@
// @dart = 2.7
/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A:checkedTypeArgument,typeArgument*/
class A<T> {}
/*class: B:checkedInstance*/

View file

@ -16,10 +16,10 @@ main() {
test7();
}
/*class: A1:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A1:checkedTypeArgument,typeArgument*/
class A1<T> {}
/*class: B1:checks=[],onlyForRti,typeArgument*/
/*class: B1:typeArgument*/
class B1 extends A1<int> {}
@pragma('dart2js:noInline')
@ -36,12 +36,12 @@ A1<String> method1c() => null;
@pragma('dart2js:noInline')
bool _test1(f) => f is A1<int> Function();
/*spec.class: A2:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: A2:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A2:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: A2:checkedTypeArgument,typeArgument*/
class A2<T> {}
/*spec.class: B2:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: B2:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: B2:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: B2:checkedTypeArgument,typeArgument*/
class B2 extends A2<int> {}
@pragma('dart2js:noInline')
@ -58,12 +58,12 @@ void method2c(A2<String> a) {}
@pragma('dart2js:noInline')
bool _test2(f) => f is void Function(A2<int>);
/*spec.class: A3:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: A3:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: A3:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: A3:checkedTypeArgument,typeArgument*/
class A3<T> {}
/*spec.class: B3:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*prod.class: B3:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*spec.class: B3:checkedInstance,checkedTypeArgument,typeArgument*/
/*prod.class: B3:checkedTypeArgument,typeArgument*/
class B3 extends A3<int> {}
@pragma('dart3js:noInline')
@ -80,10 +80,10 @@ void method3c(A3<String> a) {}
@pragma('dart3js:noInline')
_test3(f) => f is void Function(B3);
/*class: A4:checks=[],onlyForRti,typeArgument*/
/*class: A4:typeArgument*/
class A4<T> {}
/*class: B4:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B4:checkedTypeArgument,typeArgument*/
class B4 extends A4<int> {}
@pragma('dart4js:noInline')
@ -100,10 +100,10 @@ A4<String> method4c() => null;
@pragma('dart4js:noInline')
_test4(f) => f is B4 Function();
/*class: A5:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A5:checkedTypeArgument,typeArgument*/
class A5<T> {}
/*class: B5:checks=[],onlyForRti,typeArgument*/
/*class: B5:typeArgument*/
class B5 extends A5<int> {}
@pragma('dart2js:noInline')
@ -120,10 +120,10 @@ void method5c(void Function(A5<String>) f) => null;
@pragma('dart2js:noInline')
bool _test5(f) => f is void Function(void Function(A5<int>));
/*class: A6:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A6:checkedTypeArgument,typeArgument*/
class A6<T> {}
/*class: B6:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B6:checkedTypeArgument,typeArgument*/
class B6 extends A6<int> {}
@pragma('dart6js:noInline')
@ -140,10 +140,10 @@ void Function(A6<String>) method6c() => null;
@pragma('dart6js:noInline')
_test6(f) => f is void Function(B6) Function();
/*class: A7:checks=[],onlyForRti,typeArgument*/
/*class: A7:typeArgument*/
class A7<T> {}
/*class: B7:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: B7:checkedTypeArgument,typeArgument*/
class B7 extends A7<int> {}
@pragma('dart7js:noInline')

View file

@ -6,16 +6,16 @@
import 'package:expect/expect.dart';
/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A:checkedTypeArgument,typeArgument*/
class A {}
/*class: B:checks=[$isA],onlyForRti,typeArgument*/
/*class: B:typeArgument*/
class B implements A {}
/*class: C:checkedInstance,checks=[],instance*/
class C<T> {}
/*class: D:checks=[],onlyForRti,typeArgument*/
/*class: D:typeArgument*/
class D {}
/*class: E:checks=[],instance*/

View file

@ -6,16 +6,16 @@
import 'package:expect/expect.dart';
/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
/*class: A:checkedTypeArgument,typeArgument*/
class A {}
/*class: B:checks=[$isA],onlyForRti,typeArgument*/
/*class: B:typeArgument*/
class B implements A {}
/*class: C:checkedInstance,checks=[],instance*/
class C<T> {}
/*class: D:checks=[],onlyForRti,typeArgument*/
/*class: D:typeArgument*/
class D {}
@pragma('dart2js:noInline')

View file

@ -6,10 +6,10 @@
import 'package:expect/expect.dart';
/*class: Class1:checks=[],onlyForRti,typeLiteral*/
/*class: Class1:typeLiteral*/
class Class1 {}
/*class: Class2:checks=[],onlyForRti,typeLiteral*/
/*class: Class2:typeLiteral*/
class Class2<X> {}
void main() {