mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 16:44:59 +00:00
Fix rti encoding of generic methods
R=sigmund@google.com Review-Url: https://codereview.chromium.org/2565413002 .
This commit is contained in:
parent
53dd819a4c
commit
d4c9dc92e1
|
@ -1434,8 +1434,11 @@ class Types implements DartTypes {
|
|||
* [type], or [:null:] if [type] does not contain type variables.
|
||||
*/
|
||||
static ClassElement getClassContext(DartType type) {
|
||||
TypeVariableType typeVariable = type.typeVariableOccurrence;
|
||||
if (typeVariable == null) return null;
|
||||
ClassElement contextClass;
|
||||
type.forEachTypeVariable((TypeVariableType typeVariable) {
|
||||
if (typeVariable.element.typeDeclaration is! ClassElement) return;
|
||||
contextClass = typeVariable.element.typeDeclaration;
|
||||
});
|
||||
// GENERIC_METHODS: When generic method support is complete enough to
|
||||
// include a runtime value for method type variables this must be updated.
|
||||
// For full support the global assumption that all type variables are
|
||||
|
@ -1444,8 +1447,7 @@ class Types implements DartTypes {
|
|||
// type cannot be [ClassElement] and the caller must be prepared to look in
|
||||
// two locations, not one. Currently we ignore method type variables by
|
||||
// returning in the next statement.
|
||||
if (typeVariable.element.typeDeclaration is! ClassElement) return null;
|
||||
return typeVariable.element.typeDeclaration;
|
||||
return contextClass;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -609,8 +609,10 @@ class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
|
|||
jsAst.Expression getTypeRepresentation(
|
||||
DartType type, OnVariableCallback onVariable,
|
||||
[ShouldEncodeTypedefCallback shouldEncodeTypedef]) {
|
||||
// GENERIC_METHODS: When generic method support is complete enough to
|
||||
// include a runtime value for method type variables this must be updated.
|
||||
return representationGenerator.getTypeRepresentation(
|
||||
type, onVariable, shouldEncodeTypedef);
|
||||
type.dynamifyMethodTypeVariableType, onVariable, shouldEncodeTypedef);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -2607,18 +2607,21 @@ abstract class Closure implements Function {
|
|||
})(#, #)''',
|
||||
RAW_DART_FUNCTION_REF(getType),
|
||||
functionType);
|
||||
} else if (!isStatic
|
||||
&& JS('bool', 'typeof # == "function"', functionType)) {
|
||||
var getReceiver = isIntercepted
|
||||
? RAW_DART_FUNCTION_REF(BoundClosure.receiverOf)
|
||||
: RAW_DART_FUNCTION_REF(BoundClosure.selfOf);
|
||||
signatureFunction = JS(
|
||||
'',
|
||||
'function(f,r){'
|
||||
'return function(){'
|
||||
'return f.apply({\$receiver:r(this)},arguments)'
|
||||
'}'
|
||||
'}(#,#)', functionType, getReceiver);
|
||||
} else if (JS('bool', 'typeof # == "function"', functionType)) {
|
||||
if (isStatic) {
|
||||
signatureFunction = functionType;
|
||||
} else {
|
||||
var getReceiver = isIntercepted
|
||||
? RAW_DART_FUNCTION_REF(BoundClosure.receiverOf)
|
||||
: RAW_DART_FUNCTION_REF(BoundClosure.selfOf);
|
||||
signatureFunction = JS(
|
||||
'',
|
||||
'function(f,r){'
|
||||
'return function(){'
|
||||
'return f.apply({\$receiver:r(this)},arguments)'
|
||||
'}'
|
||||
'}(#,#)', functionType, getReceiver);
|
||||
}
|
||||
} else {
|
||||
throw 'Error in reflectionInfo.';
|
||||
}
|
||||
|
|
50
tests/language/generic_method_types_test.dart
Normal file
50
tests/language/generic_method_types_test.dart
Normal file
|
@ -0,0 +1,50 @@
|
|||
// 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';
|
||||
|
||||
typedef O Convert<I, O>(I input);
|
||||
typedef Other(a, b);
|
||||
|
||||
class Mixin<E> {
|
||||
E convert1<I>(I input) => null;
|
||||
}
|
||||
|
||||
class Class<F> extends Object with Mixin<F> {
|
||||
O convert2<O>(F input) => null;
|
||||
}
|
||||
|
||||
O convert<I, O>(I input) => null;
|
||||
|
||||
test1() {
|
||||
var val = new Class<String>();
|
||||
Expect.isTrue(val.convert1 is Convert);
|
||||
Expect.isTrue(val.convert1 is Convert<String, String>);
|
||||
Expect.isTrue(val.convert1 is Convert<int, String>);
|
||||
Expect.isFalse(val.convert1 is Convert<String, int>);
|
||||
Expect.isFalse(val.convert1 is Other);
|
||||
}
|
||||
|
||||
test2() {
|
||||
var val = new Class<String>();
|
||||
Expect.isTrue(val.convert2 is Convert);
|
||||
Expect.isTrue(val.convert2 is Convert<String, String>);
|
||||
Expect.isTrue(val.convert2 is Convert<String, int>);
|
||||
Expect.isFalse(val.convert2 is Convert<int, String>);
|
||||
Expect.isFalse(val.convert2 is Other);
|
||||
}
|
||||
|
||||
test3() {
|
||||
Expect.isTrue(convert is Convert);
|
||||
Expect.isTrue(convert is Convert<String, String>);
|
||||
Expect.isTrue(convert is Convert<String, int>);
|
||||
Expect.isTrue(convert is Convert<int, String>);
|
||||
Expect.isFalse(convert is Other);
|
||||
}
|
||||
|
||||
main() {
|
||||
test1(); /// 01: ok
|
||||
test2(); /// 02: ok
|
||||
test3(); /// 03: ok
|
||||
}
|
Loading…
Reference in a new issue