Skip to content

Commit b6a0c50

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[dart2js] Support conversion of local function type variables from K to J model
This CL adds support for converting local function type variables from the K model to the J model. The entity use for the J model type variables isn't created before the closure classes and closure call methods have been created. Therefore, the [ClosureData] is now registered with the [JsToFrontendMap] object, once computed, allowing conversion of local function type variables. Conversion of [BackendUsage] is moved after closure creation because [RuntimeTypeUse] can refer to local function type variables. Closes #42088 Change-Id: Ifc00e69b5db0dd05710ea97017c41e8c7f5e520e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153080 Reviewed-by: Mayank Patke <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 0ce8398 commit b6a0c50

File tree

4 files changed

+60
-8
lines changed

4 files changed

+60
-8
lines changed

pkg/compiler/lib/src/js_model/js_world_builder.dart

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ class JsClosedWorldBuilder {
6262
OutputUnitData kOutputUnitData) {
6363
JsToFrontendMap map = new JsToFrontendMapImpl(_elementMap);
6464

65-
BackendUsage backendUsage =
66-
_convertBackendUsage(map, closedWorld.backendUsage);
6765
NativeData nativeData = _convertNativeData(map, closedWorld.nativeData);
6866
_elementMap.nativeData = nativeData;
6967
InterceptorData interceptorData =
@@ -162,7 +160,7 @@ class JsClosedWorldBuilder {
162160
}
163161

164162
RuntimeTypesNeedImpl jRtiNeed =
165-
_convertRuntimeTypesNeed(map, backendUsage, kernelRtiNeed);
163+
_convertRuntimeTypesNeed(map, kernelRtiNeed);
166164
closureData = _closureDataBuilder.createClosureEntities(
167165
this,
168166
map.toBackendMemberMap(closureModels, identity),
@@ -189,6 +187,11 @@ class JsClosedWorldBuilder {
189187
rtiNeed = jRtiNeed;
190188
}
191189

190+
map.registerClosureData(closureData);
191+
192+
BackendUsage backendUsage =
193+
_convertBackendUsage(map, closedWorld.backendUsage);
194+
192195
NoSuchMethodDataImpl oldNoSuchMethodData = closedWorld.noSuchMethodData;
193196
NoSuchMethodData noSuchMethodData = new NoSuchMethodDataImpl(
194197
map.toBackendFunctionSet(oldNoSuchMethodData.throwingImpls),
@@ -378,8 +381,8 @@ class JsClosedWorldBuilder {
378381
interceptorData.classesMixedIntoInterceptedClasses));
379382
}
380383

381-
RuntimeTypesNeed _convertRuntimeTypesNeed(JsToFrontendMap map,
382-
BackendUsage backendUsage, RuntimeTypesNeedImpl rtiNeed) {
384+
RuntimeTypesNeed _convertRuntimeTypesNeed(
385+
JsToFrontendMap map, RuntimeTypesNeedImpl rtiNeed) {
383386
Set<ClassEntity> classesNeedingTypeArguments =
384387
map.toBackendClassSet(rtiNeed.classesNeedingTypeArguments);
385388
Set<FunctionEntity> methodsNeedingTypeArguments =
@@ -597,6 +600,13 @@ abstract class JsToFrontendMap {
597600

598601
ConstantValue toBackendConstant(ConstantValue value, {bool allowNull: false});
599602

603+
/// Register [closureData] with this map.
604+
///
605+
/// [ClosureData] holds the relation between local function and the backend
606+
/// entities. Before this has been registered, type variables of local
607+
/// functions cannot be converted into backend equivalents.
608+
void registerClosureData(ClosureData closureData);
609+
600610
Set<LibraryEntity> toBackendLibrarySet(Iterable<LibraryEntity> set) {
601611
return set.map(toBackendLibrary).toSet();
602612
}
@@ -671,6 +681,7 @@ Map<K, V2> convertMap<K, V1, V2>(
671681

672682
class JsToFrontendMapImpl extends JsToFrontendMap {
673683
final JsKernelToElementMap _backend;
684+
ClosureData _closureData;
674685

675686
JsToFrontendMapImpl(this._backend);
676687

@@ -707,10 +718,23 @@ class JsToFrontendMapImpl extends JsToFrontendMap {
707718
return _backend.members.getEntity(member.memberIndex);
708719
}
709720

721+
@override
722+
void registerClosureData(ClosureData closureData) {
723+
assert(_closureData == null, "Closure data has already been registered.");
724+
_closureData = closureData;
725+
}
726+
710727
TypeVariableEntity toBackendTypeVariable(TypeVariableEntity typeVariable) {
711728
if (typeVariable is KLocalTypeVariable) {
712-
failedAt(
713-
typeVariable, "Local function type variables are not supported.");
729+
if (_closureData == null) {
730+
failedAt(
731+
typeVariable, "Local function type variables are not supported.");
732+
}
733+
ClosureRepresentationInfo info =
734+
_closureData.getClosureInfo(typeVariable.typeDeclaration.node);
735+
return _backend.elementEnvironment
736+
.getFunctionTypeVariables(info.callMethod)[typeVariable.index]
737+
.element;
714738
}
715739
IndexedTypeVariable indexedTypeVariable = typeVariable;
716740
return _backend.typeVariables

pkg/compiler/lib/src/kernel/kelements.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ class KLocalFunction implements Local {
281281

282282
class KLocalTypeVariable implements TypeVariableEntity {
283283
@override
284-
final Entity typeDeclaration;
284+
final KLocalFunction typeDeclaration;
285285
@override
286286
final String name;
287287
@override

tests/dart2js/42088_test.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Regression test for issue 42088.
6+
7+
class Foo<T> {}
8+
9+
void main() {
10+
var f = <T>() => Foo<T>().runtimeType;
11+
12+
print(f<int>());
13+
print(f<String>());
14+
}

tests/dart2js_2/42088_test.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Regression test for issue 42088.
6+
7+
class Foo<T> {}
8+
9+
void main() {
10+
var f = <T>() => Foo<T>().runtimeType;
11+
12+
print(f<int>());
13+
print(f<String>());
14+
}

0 commit comments

Comments
 (0)