mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:16:51 +00:00
Use default type for type variable bounds.
Change-Id: I5d21a16a76eb6cd898e8e11104d0be0f7e669426 Reviewed-on: https://dart-review.googlesource.com/59420 Reviewed-by: Stephen Adams <sra@google.com>
This commit is contained in:
parent
52d7a3043a
commit
7321f938d5
|
@ -1455,6 +1455,12 @@ abstract class ElementEnvironment {
|
|||
/// `Object`.
|
||||
DartType getTypeVariableBound(TypeVariableEntity typeVariable);
|
||||
|
||||
/// The default type of the [typeVariable].
|
||||
///
|
||||
/// This is the type used as the default type argument when no explicit type
|
||||
/// argument is passed.
|
||||
DartType getTypeVariableDefaultType(TypeVariableEntity typeVariable);
|
||||
|
||||
/// Returns the type of [function].
|
||||
FunctionType getFunctionType(FunctionEntity function);
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ class ParameterStubGenerator {
|
|||
targetArguments[count++] = _rtiEncoder.getTypeRepresentation(
|
||||
_emitter,
|
||||
_closedWorld.elementEnvironment
|
||||
.getTypeVariableBound(typeVariable.element),
|
||||
.getTypeVariableDefaultType(typeVariable.element),
|
||||
(_) => _emitter.constantReference(new NullConstantValue()));
|
||||
} else {
|
||||
String jsName = '\$${typeVariable.element.name}';
|
||||
|
|
|
@ -682,6 +682,12 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin {
|
|||
return data.getBound(this);
|
||||
}
|
||||
|
||||
DartType _getTypeVariableDefaultType(IndexedTypeVariable typeVariable) {
|
||||
assert(checkFamily(typeVariable));
|
||||
TypeVariableData data = _typeVariables.getData(typeVariable);
|
||||
return data.getDefaultType(this);
|
||||
}
|
||||
|
||||
ClassEntity _getAppliedMixin(IndexedClass cls) {
|
||||
assert(checkFamily(cls));
|
||||
ClassData data = _classes.getData(cls);
|
||||
|
@ -1280,6 +1286,11 @@ class KernelToElementMapForImpactImpl extends KernelToElementMapBase
|
|||
return super._getTypeVariableBound(typeVariable);
|
||||
}
|
||||
|
||||
DartType _getTypeVariableDefaultType(TypeVariableEntity typeVariable) {
|
||||
if (typeVariable is KLocalTypeVariable) return typeVariable.defaultType;
|
||||
return super._getTypeVariableDefaultType(typeVariable);
|
||||
}
|
||||
|
||||
@override
|
||||
void _forEachNestedClosure(
|
||||
MemberEntity member, void f(FunctionEntity closure)) {
|
||||
|
@ -1373,6 +1384,8 @@ class KernelToElementMapForImpactImpl extends KernelToElementMapBase
|
|||
index = 0;
|
||||
for (ir.TypeParameter typeParameter in function.typeParameters) {
|
||||
typeVariables[index].bound = getDartType(typeParameter.bound);
|
||||
typeVariables[index].defaultType =
|
||||
getDartType(typeParameter.defaultType);
|
||||
index++;
|
||||
}
|
||||
localFunction.functionType = getFunctionType(function);
|
||||
|
@ -1487,6 +1500,11 @@ class KernelElementEnvironment extends ElementEnvironment {
|
|||
return elementMap._getTypeVariableBound(typeVariable);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType getTypeVariableDefaultType(TypeVariableEntity typeVariable) {
|
||||
return elementMap._getTypeVariableDefaultType(typeVariable);
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ClassEntity cls, List<DartType> typeArguments) {
|
||||
|
|
|
@ -1014,6 +1014,7 @@ class TypedefData {
|
|||
class TypeVariableData {
|
||||
final ir.TypeParameter node;
|
||||
DartType _bound;
|
||||
DartType _defaultType;
|
||||
|
||||
TypeVariableData(this.node);
|
||||
|
||||
|
@ -1021,6 +1022,10 @@ class TypeVariableData {
|
|||
return _bound ??= elementMap.getDartType(node.bound);
|
||||
}
|
||||
|
||||
DartType getDefaultType(KernelToElementMap elementMap) {
|
||||
return _defaultType ??= elementMap.getDartType(node.defaultType);
|
||||
}
|
||||
|
||||
TypeVariableData copy() {
|
||||
return new TypeVariableData(node);
|
||||
}
|
||||
|
|
|
@ -293,6 +293,7 @@ class KLocalTypeVariable implements TypeVariableEntity {
|
|||
final String name;
|
||||
final int index;
|
||||
DartType bound;
|
||||
DartType defaultType;
|
||||
|
||||
KLocalTypeVariable(this.typeDeclaration, this.name, this.index);
|
||||
|
||||
|
|
|
@ -113,8 +113,6 @@ main(args) {
|
|||
new Class2().method5<int>(0);
|
||||
new Class3().method6<int>(0);
|
||||
dynamic c3 = args != null ? new Class3() : new Class2();
|
||||
// TODO(johnniwinther): Expected bounds should be `dynamic` when CFE supports
|
||||
// instantiate-to-bound.
|
||||
c3.method6(0); // Missing type arguments.
|
||||
try {
|
||||
dynamic c2 = args == null ? new Class3() : new Class2();
|
||||
|
@ -162,8 +160,8 @@ Class3.method6:
|
|||
"foo" is int = false
|
||||
|
||||
Class3.method6:
|
||||
0 is Object = true
|
||||
"foo" is Object = true
|
||||
0 is dynamic = true
|
||||
"foo" is dynamic = true
|
||||
|
||||
Class2.method6:
|
||||
0 is int = true
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// 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=-Ddart.isdart2js=true
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
|
@ -21,7 +22,8 @@ check(expected, actual) {
|
|||
print('a: $expected');
|
||||
print('b: $actual');
|
||||
if (((actual[0] == Object && expected[0] == dynamic) ||
|
||||
(actual[0] == dynamic && expected[0] == Object))) {
|
||||
(actual[0] == dynamic && expected[0] == Object)) &&
|
||||
!const bool.fromEnvironment('dart.isdart2js')) {
|
||||
// TODO(32483): dartdevk sometimes defaults type to 'Object' when 'dynamic'
|
||||
// is required. Remove this hack when fixed.
|
||||
// TODO(31581): dart2js needs instantiate-to-bound to generic 'dynamic'
|
||||
|
|
Loading…
Reference in a new issue