c878108cc8
All non-pubspec changes generated by `dart format pkg/compiler`. Change-Id: Iadaa70974816d96ccb47813fe72d5a2bb83d6bda Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400181 Reviewed-by: Nate Biggs <natebiggs@google.com> Commit-Queue: Mayank Patke <fishythefish@google.com>
234 lines
5.9 KiB
Dart
234 lines
5.9 KiB
Dart
// Copyright (c) 2017, 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:compiler/src/commandline_options.dart';
|
|
import 'package:compiler/src/common/elements.dart';
|
|
import 'package:compiler/src/compiler.dart';
|
|
import 'package:compiler/src/elements/entities.dart';
|
|
import 'package:compiler/src/elements/names.dart';
|
|
import 'package:compiler/src/js/js.dart' as js;
|
|
import 'package:compiler/src/js_model/js_strategy.dart';
|
|
import 'package:compiler/src/js_model/js_world.dart' show JClosedWorld;
|
|
import 'package:expect/async_helper.dart';
|
|
import 'package:expect/expect.dart';
|
|
import '../helpers/d8_helper.dart';
|
|
import 'package:compiler/src/util/memory_compiler.dart';
|
|
|
|
const String SOURCE = r'''
|
|
@pragma('dart2js:noInline')
|
|
method1<T>(T t) {
|
|
print('method1:');
|
|
print('$t is $T = ${t is T}');
|
|
print('"foo" is $T = ${"foo" is T}');
|
|
print('');
|
|
}
|
|
|
|
@pragma('dart2js:noInline')
|
|
method2<T, S>(S s, T t) {
|
|
print('method2:');
|
|
print('$t is $T = ${t is T}');
|
|
print('$s is $T = ${s is T}');
|
|
print('$t is $S = ${t is S}');
|
|
print('$s is $S = ${s is S}');
|
|
print('');
|
|
}
|
|
|
|
@pragma('dart2js:tryInline')
|
|
method3<T, S>(T t, S s) {
|
|
print('method3:');
|
|
print('$t is $T = ${t is T}');
|
|
print('$s is $T = ${s is T}');
|
|
print('$t is $S = ${t is S}');
|
|
print('$s is $S = ${s is S}');
|
|
print('');
|
|
}
|
|
|
|
class Class1<T> {
|
|
final int index;
|
|
|
|
Class1(this.index);
|
|
|
|
String toString() => 'c$index';
|
|
}
|
|
|
|
method4<T>(int index) => Class1<T>(index);
|
|
|
|
testMethod4() {
|
|
print('method4:');
|
|
var c1 = method4<int>(1);
|
|
var c2 = method4<String>(2);
|
|
print('$c1 is Class1<int> = ${c1 is Class1<int>}');
|
|
print('$c2 is Class1<int> = ${c2 is Class1<int>}');
|
|
print('$c1 is Class1<String> = ${c1 is Class1<String>}');
|
|
print('$c2 is Class1<String> = ${c2 is Class1<String>}');
|
|
print('');
|
|
}
|
|
|
|
class Class2 {
|
|
@pragma('dart2js:tryInline')
|
|
method5<T>(T t) {
|
|
print('Class2.method5:');
|
|
print('$t is $T = ${t is T}');
|
|
print('"foo" is $T = ${"foo" is T}');
|
|
print('');
|
|
}
|
|
|
|
@pragma('dart2js:noInline')
|
|
method6(o) {
|
|
print('Class2.method6:');
|
|
print('$o is int = ${o is int}');
|
|
print('$o is String = ${o is String}');
|
|
print('');
|
|
}
|
|
}
|
|
|
|
class Class3 {
|
|
@pragma('dart2js:noInline')
|
|
method6<T>(T t) {
|
|
print('Class3.method6:');
|
|
print('$t is $T = ${t is T}');
|
|
print('"foo" is $T = ${"foo" is T}');
|
|
print('');
|
|
}
|
|
}
|
|
|
|
class Class4<T> {
|
|
Function method7<Q>() {
|
|
foo(T t, Q q) => '';
|
|
return foo;
|
|
}
|
|
}
|
|
|
|
// Nested generic local function.
|
|
outside<T>() {
|
|
nested<T>(T t) => '';
|
|
return nested;
|
|
}
|
|
|
|
main(args) {
|
|
method1<int>(0);
|
|
method2<String, double>(0.5, 'foo');
|
|
method3<double, String>(1.5, 'bar');
|
|
testMethod4();
|
|
Class2().method5<int>(0);
|
|
Class3().method6<int>(0);
|
|
dynamic c3 = args != null ? Class3() : Class2();
|
|
c3.method6(0); // Missing type arguments.
|
|
try {
|
|
dynamic c2 = args == null ? Class3() : Class2();
|
|
c2.method6(0); // Valid call.
|
|
c2.method6<int>(0); // Extra type arguments.
|
|
} catch (e) {
|
|
print('noSuchMethod: Class2.method6<int>');
|
|
print('');
|
|
}
|
|
var c = Class4<bool>();
|
|
print((c.method7<int>()).runtimeType);
|
|
outside();
|
|
}
|
|
''';
|
|
|
|
const String OUTPUT = r'''
|
|
method1:
|
|
0 is int = true
|
|
"foo" is int = false
|
|
|
|
method2:
|
|
foo is String = true
|
|
0.5 is String = false
|
|
foo is double = false
|
|
0.5 is double = true
|
|
|
|
method3:
|
|
1.5 is double = true
|
|
bar is double = false
|
|
1.5 is String = false
|
|
bar is String = true
|
|
|
|
method4:
|
|
c1 is Class1<int> = true
|
|
c2 is Class1<int> = false
|
|
c1 is Class1<String> = false
|
|
c2 is Class1<String> = true
|
|
|
|
Class2.method5:
|
|
0 is int = true
|
|
"foo" is int = false
|
|
|
|
Class3.method6:
|
|
0 is int = true
|
|
"foo" is int = false
|
|
|
|
Class3.method6:
|
|
0 is dynamic = true
|
|
"foo" is dynamic = true
|
|
|
|
Class2.method6:
|
|
0 is int = true
|
|
0 is String = false
|
|
|
|
noSuchMethod: Class2.method6<int>
|
|
|
|
(bool, int) => String
|
|
''';
|
|
|
|
main(List<String> args) {
|
|
asyncTest(() async {
|
|
D8Result result = await runWithD8(
|
|
memorySourceFiles: {'main.dart': SOURCE},
|
|
options: [
|
|
Flags.disableRtiOptimization,
|
|
'--libraries-spec=$sdkLibrariesSpecificationUri',
|
|
],
|
|
expectedOutput: OUTPUT,
|
|
printJs: args.contains('-v'),
|
|
);
|
|
Compiler compiler = result.compilationResult.compiler!;
|
|
JsBackendStrategy backendStrategy = compiler.backendStrategy;
|
|
JClosedWorld closedWorld = compiler.backendClosedWorldForTesting!;
|
|
ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
|
|
|
|
void checkMethod(
|
|
String methodName, {
|
|
String? className,
|
|
required int expectedParameterCount,
|
|
}) {
|
|
FunctionEntity? method;
|
|
if (className != null) {
|
|
ClassEntity? cls = elementEnvironment.lookupClass(
|
|
elementEnvironment.mainLibrary!,
|
|
className,
|
|
);
|
|
Expect.isNotNull(cls, "Class '$className' not found.");
|
|
method =
|
|
elementEnvironment.lookupClassMember(
|
|
cls!,
|
|
Name(methodName, cls.library.canonicalUri),
|
|
)
|
|
as FunctionEntity?;
|
|
Expect.isNotNull(method, "Method '$methodName' not found in $cls.");
|
|
} else {
|
|
method =
|
|
elementEnvironment.lookupLibraryMember(
|
|
elementEnvironment.mainLibrary!,
|
|
methodName,
|
|
)
|
|
as FunctionEntity?;
|
|
Expect.isNotNull(method, "Method '$methodName' not found.");
|
|
}
|
|
js.Fun fun = backendStrategy.generatedCode[method] as js.Fun;
|
|
Expect.equals(
|
|
expectedParameterCount,
|
|
fun.params.length,
|
|
"Unexpected parameter count for $method:\n${js.nodeToString(fun)}",
|
|
);
|
|
}
|
|
|
|
checkMethod('method1', expectedParameterCount: 2);
|
|
checkMethod('method2', expectedParameterCount: 4);
|
|
checkMethod('method6', className: 'Class2', expectedParameterCount: 1);
|
|
checkMethod('method6', className: 'Class3', expectedParameterCount: 2);
|
|
});
|
|
}
|