From 7321f938d5c3308d9b7355a797030b7d293f3145 Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Tue, 12 Jun 2018 09:05:09 +0000 Subject: [PATCH] Use default type for type variable bounds. Change-Id: I5d21a16a76eb6cd898e8e11104d0be0f7e669426 Reviewed-on: https://dart-review.googlesource.com/59420 Reviewed-by: Stephen Adams --- pkg/compiler/lib/src/common_elements.dart | 6 ++++++ .../js_emitter/parameter_stub_generator.dart | 2 +- .../lib/src/kernel/element_map_impl.dart | 18 ++++++++++++++++++ pkg/compiler/lib/src/kernel/env.dart | 5 +++++ pkg/compiler/lib/src/kernel/kelements.dart | 1 + .../generic_methods/generic_method_test.dart | 6 ++---- .../language_2/function_call_generic_test.dart | 4 +++- 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart index c4419b51f9d..738bd388907 100644 --- a/pkg/compiler/lib/src/common_elements.dart +++ b/pkg/compiler/lib/src/common_elements.dart @@ -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); diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart index 492adf30fa9..d3267ab0617 100644 --- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart +++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart @@ -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}'; diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart index e566ff0f45b..ee5006d1342 100644 --- a/pkg/compiler/lib/src/kernel/element_map_impl.dart +++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart @@ -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 typeArguments) { diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart index dde76e858b1..dcef78f905f 100644 --- a/pkg/compiler/lib/src/kernel/env.dart +++ b/pkg/compiler/lib/src/kernel/env.dart @@ -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); } diff --git a/pkg/compiler/lib/src/kernel/kelements.dart b/pkg/compiler/lib/src/kernel/kelements.dart index 3b18fbca14e..38d7dd6a761 100644 --- a/pkg/compiler/lib/src/kernel/kelements.dart +++ b/pkg/compiler/lib/src/kernel/kelements.dart @@ -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); diff --git a/tests/compiler/dart2js/generic_methods/generic_method_test.dart b/tests/compiler/dart2js/generic_methods/generic_method_test.dart index e907015be81..ae1e4fdb911 100644 --- a/tests/compiler/dart2js/generic_methods/generic_method_test.dart +++ b/tests/compiler/dart2js/generic_methods/generic_method_test.dart @@ -113,8 +113,6 @@ main(args) { new Class2().method5(0); new Class3().method6(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 diff --git a/tests/language_2/function_call_generic_test.dart b/tests/language_2/function_call_generic_test.dart index b98584e782a..db40488e1a6 100644 --- a/tests/language_2/function_call_generic_test.dart +++ b/tests/language_2/function_call_generic_test.dart @@ -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'