blob: 75619553b82498eec1b5fda10d0a48c76cacd53e [file] [log] [blame]
// Copyright (c) 2015, 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.
// @dart = 2.7
library tests.web.interop_anonymous_unreachable_test;
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import '../helpers/compiler_helper.dart';
testUnreachableCrash() async {
print("-- unreachable code doesn't crash the compiler --");
// This test is a regression for Issue #24974
String generated = await compile("""
import 'package:js/js.dart';
@JS() @anonymous
class UniqueLongNameForTesting_A {
external factory UniqueLongNameForTesting_A();
}
main() {}
""", returnAll: true);
// the code should not be included in the output either.
Expect.isFalse(generated.contains("UniqueLongNameForTesting_A"));
}
testTreeShakingJsInteropTypes() async {
print('-- tree-shaking interop types --');
String program = """
import 'package:js/js.dart';
// reachable and allocated
@JS() @anonymous
class UniqueLongNameForTesting_A {
external bool get x;
external UniqueLongNameForTesting_D get d;
external UniqueLongNameForTesting_E get e;
external factory UniqueLongNameForTesting_A(
{UniqueLongNameForTesting_B arg0});
}
// visible through the parameter above, but not used.
@JS() @anonymous
class UniqueLongNameForTesting_B {
external factory UniqueLongNameForTesting_B();
}
// unreachable
@JS() @anonymous
class UniqueLongNameForTesting_C {
external factory UniqueLongNameForTesting_C();
}
// visible and reached through `d`.
@JS() @anonymous
class UniqueLongNameForTesting_D {
external factory UniqueLongNameForTesting_D();
}
// visible through `e`, but not reached.
@JS() @anonymous
class UniqueLongNameForTesting_E {
external factory UniqueLongNameForTesting_E();
}
main() {
print(new UniqueLongNameForTesting_A().x);
print(new UniqueLongNameForTesting_A().d);
}
""";
print(' - no tree-shaking by default -');
String generated1 = await compile(program, returnAll: true);
Expect.isTrue(generated1.contains("UniqueLongNameForTesting_A"));
Expect.isTrue(generated1.contains("UniqueLongNameForTesting_D"));
Expect.isTrue(generated1.contains("UniqueLongNameForTesting_B"));
Expect.isTrue(generated1.contains("UniqueLongNameForTesting_C"));
Expect.isTrue(generated1.contains("UniqueLongNameForTesting_E"));
}
testTreeShakingNativeTypes() async {
print('-- tree-shaking other native types --');
String program = """
import 'dart:html';
import 'package:js/js.dart';
@JS() @anonymous
class UniqueLongNameForTesting_A {
external dynamic get x;
}
@JS() @anonymous
class UniqueLongNameForTesting_B {
external dynamic get y;
}
main() {
print(new UniqueLongNameForTesting_A().x);
}
""";
print(' - allocation effect of dynamic excludes native types -');
String generated1 = await compile(program, returnAll: true);
Expect.isTrue(generated1.contains("UniqueLongNameForTesting_A"));
// any js-interop type could be allocated by `get x`
Expect.isTrue(generated1.contains("UniqueLongNameForTesting_B"));
// but we exclude other native types like HTMLAudioElement
Expect.isFalse(generated1.contains("HTMLAudioElement"));
print(' - declared native types are included in allocation effect -');
String program2 = """
import 'dart:html';
import 'package:js/js.dart';
@JS() @anonymous
class UniqueLongNameForTesting_A {
external AudioElement get x;
}
main() {
print(new UniqueLongNameForTesting_A().x is AudioElement);
}
""";
String generated3 = await compile(program2, returnAll: true);
Expect.isTrue(generated3.contains("UniqueLongNameForTesting_A"));
Expect.isTrue(generated3.contains("HTMLAudioElement"));
program2 = """
import 'dart:html';
import 'package:js/js.dart';
@JS() @anonymous
class UniqueLongNameForTesting_A {
external dynamic get x;
}
main() {
print(new UniqueLongNameForTesting_A().x is AudioElement);
}
""";
generated3 = await compile(program2, returnAll: true);
Expect.isTrue(generated3.contains("UniqueLongNameForTesting_A"));
// This extra check is to make sure that we don't include HTMLAudioElement
// just because of the is-check. It is optimized away in this case because
// we believe it was never instantiated.
Expect.isFalse(generated3.contains("HTMLAudioElement"));
}
main() {
runTests() async {
await testUnreachableCrash();
await testTreeShakingJsInteropTypes();
await testTreeShakingNativeTypes();
}
asyncTest(() async {
print('--test from kernel------------------------------------------------');
await runTests();
});
}