mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 14:49:43 +00:00
Handle generic jsinterop classes as type arguments.
Change-Id: I89d8a77d632cf6d4f8adffa84f042a1c03a79f26 Reviewed-on: https://dart-review.googlesource.com/56665 Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
c6129f768e
commit
39b0efd613
|
@ -2146,12 +2146,21 @@ class TypeRepresentationGenerator
|
|||
|
||||
jsAst.Expression visitInterfaceType(InterfaceType type, Emitter emitter) {
|
||||
jsAst.Expression name = getJavaScriptClassName(type.element, emitter);
|
||||
if (_nativeData.isJsInteropClass(type.element)) {
|
||||
return getJsInteropTypeArguments(type.typeArguments.length, name: name);
|
||||
jsAst.Expression result;
|
||||
if (type.treatAsRaw) {
|
||||
result = name;
|
||||
} else {
|
||||
// Visit all type arguments. This is done even for jsinterop classes to
|
||||
// enforce the invariant that [onVariable] is called for each type
|
||||
// variable in the type.
|
||||
result = visitList(type.typeArguments, emitter, head: name);
|
||||
if (_nativeData.isJsInteropClass(type.element)) {
|
||||
// Replace type arguments of generic jsinterop classes with 'any' type.
|
||||
result =
|
||||
getJsInteropTypeArguments(type.typeArguments.length, name: name);
|
||||
}
|
||||
}
|
||||
return type.treatAsRaw
|
||||
? name
|
||||
: visitList(type.typeArguments, emitter, head: name);
|
||||
return result;
|
||||
}
|
||||
|
||||
jsAst.Expression visitList(List<DartType> types, Emitter emitter,
|
||||
|
|
|
@ -3092,6 +3092,7 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
|||
}
|
||||
|
||||
void visitTypeInfoExpression(HTypeInfoExpression node) {
|
||||
DartType type = node.dartType;
|
||||
List<js.Expression> arguments = <js.Expression>[];
|
||||
for (HInstruction input in node.inputs) {
|
||||
use(input);
|
||||
|
@ -3103,19 +3104,19 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
|||
int index = 0;
|
||||
js.Expression result = _rtiEncoder.getTypeRepresentation(
|
||||
_emitter.emitter,
|
||||
node.dartType,
|
||||
type,
|
||||
(TypeVariableType variable) => arguments[index++]);
|
||||
assert(
|
||||
index == node.inputs.length,
|
||||
"Not all input is read for type ${node.dartType}: "
|
||||
"Not all input is read for type ${type}: "
|
||||
"$index of ${node.inputs}.");
|
||||
push(result);
|
||||
return;
|
||||
|
||||
case TypeInfoExpressionKind.INSTANCE:
|
||||
// We expect only flat types for the INSTANCE representation.
|
||||
assert((node.dartType as InterfaceType).typeArguments.length ==
|
||||
arguments.length);
|
||||
assert(
|
||||
(type as InterfaceType).typeArguments.length == arguments.length);
|
||||
_registry.registerInstantiatedClass(_commonElements.listClass);
|
||||
push(new js.ArrayInitializer(arguments)
|
||||
.withSourceInformation(node.sourceInformation));
|
||||
|
|
|
@ -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.
|
||||
|
||||
// dart2jsOptions=--strong
|
||||
|
||||
@JS()
|
||||
library foo;
|
||||
|
||||
/*class: global#JavaScriptObject:checks=[$asA,$isA]*/
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:js/js.dart';
|
||||
|
||||
/*kernel.class: A:checkedTypeArgument,checks=[],typeArgument*/
|
||||
/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
|
||||
@JS()
|
||||
@anonymous
|
||||
class A<T> {
|
||||
external factory A();
|
||||
}
|
||||
|
||||
/*class: Class1:checks=[],instance*/
|
||||
class Class1<T> {
|
||||
method() {
|
||||
// This caused and assertion failure in codegen.
|
||||
test1(new List<A<T>>.from([]));
|
||||
}
|
||||
}
|
||||
|
||||
/*class: Class2:checks=[],instance*/
|
||||
class Class2<T> {
|
||||
method() {
|
||||
// This caused and assertion failure in codegen.
|
||||
test2(new List<A<T> Function()>.from([]));
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
new Class1<int>().method();
|
||||
new Class1<String>().method();
|
||||
new Class2<int>().method();
|
||||
new Class2<String>().method();
|
||||
}
|
||||
|
||||
test1(o) {
|
||||
Expect.isTrue(o is List<A<int>>, "Expected $o to be List<A<int>>");
|
||||
Expect.isTrue(o is List<A<String>>, "Expected $o to be List<A<String>>");
|
||||
}
|
||||
|
||||
test2(o) {
|
||||
Expect.isTrue(o is List<A<int> Function()>,
|
||||
"Expected $o to be List<A<int> Function()>");
|
||||
Expect.isTrue(o is List<A<String> Function()>,
|
||||
"Expected $o to be List<A<String> Function()>");
|
||||
}
|
Loading…
Reference in a new issue