Fix deferred loading in the presence of type parameters too

(and get rid of a TODO(redemption) that I should have fixed eons ago...)

Change-Id: I218a7bddcc8256ff84b4ec03b54a858e8f5d8687
Reviewed-on: https://dart-review.googlesource.com/40180
Commit-Queue: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Emily Fortuna <efortuna@google.com>
This commit is contained in:
Sigmund Cherem 2018-02-09 00:25:26 +00:00 committed by commit-bot@chromium.org
parent ef421661dc
commit 521188f838
4 changed files with 88 additions and 25 deletions

View file

@ -600,8 +600,10 @@ class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
final Entity Function(Entity) toBackendEntity;
final TypeConverter typeConverter;
ConstantConverter(this.toBackendEntity);
ConstantConverter(this.toBackendEntity)
: typeConverter = new TypeConverter(toBackendEntity);
ConstantValue visitNull(NullConstantValue constant, _) => constant;
ConstantValue visitInt(IntConstantValue constant, _) => constant;
@ -612,12 +614,12 @@ class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
ConstantValue visitNonConstant(NonConstantValue constant, _) => constant;
ConstantValue visitFunction(FunctionConstantValue constant, _) {
return new FunctionConstantValue(
toBackendEntity(constant.element), _handleType(constant.type));
return new FunctionConstantValue(toBackendEntity(constant.element),
typeConverter.convert(constant.type));
}
ConstantValue visitList(ListConstantValue constant, _) {
var type = _handleType(constant.type);
var type = typeConverter.convert(constant.type);
List<ConstantValue> entries = _handleValues(constant.entries);
if (identical(entries, constant.entries) && type == constant.type) {
return constant;
@ -626,7 +628,7 @@ class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
}
ConstantValue visitMap(MapConstantValue constant, _) {
var type = _handleType(constant.type);
var type = typeConverter.convert(constant.type);
List<ConstantValue> keys = _handleValues(constant.keys);
List<ConstantValue> values = _handleValues(constant.values);
if (identical(keys, constant.keys) &&
@ -638,7 +640,7 @@ class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
}
ConstantValue visitConstructed(ConstructedConstantValue constant, _) {
var type = _handleType(constant.type);
var type = typeConverter.convert(constant.type);
if (type == constant.type && constant.fields.isEmpty) {
return constant;
}
@ -650,8 +652,8 @@ class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
}
ConstantValue visitType(TypeConstantValue constant, _) {
var type = _handleType(constant.type);
var representedType = _handleType(constant.representedType);
var type = typeConverter.convert(constant.type);
var representedType = typeConverter.convert(constant.representedType);
if (type == constant.type && representedType == constant.representedType) {
return constant;
}
@ -672,22 +674,6 @@ class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
return new DeferredGlobalConstantValue(referenced, constant.unit);
}
DartType _handleType(DartType type) {
if (type is InterfaceType) {
var element = toBackendEntity(type.element);
var args = type.typeArguments.map(_handleType).toList();
return new InterfaceType(element, args);
}
if (type is TypedefType) {
var element = toBackendEntity(type.element);
var args = type.typeArguments.map(_handleType).toList();
return new TypedefType(element, args);
}
// TODO(redemption): handle other types.
return type;
}
List<ConstantValue> _handleValues(List<ConstantValue> values) {
List<ConstantValue> result;
for (int i = 0; i < values.length; i++) {
@ -701,3 +687,50 @@ class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
return result ?? values;
}
}
class TypeConverter extends DartTypeVisitor<DartType, Null> {
final Entity Function(Entity) toBackendEntity;
TypeConverter(this.toBackendEntity);
DartType convert(DartType type) => type.accept(this, null);
DartType visitVoidType(VoidType type, _) => type;
DartType visitDynamicType(DynamicType type, _) => type;
DartType visitTypeVariableType(TypeVariableType type, _) {
return new TypeVariableType(toBackendEntity(type.element));
}
DartType visitFunctionTypeVariable(FunctionTypeVariable type, _) {
var bound = type.bound?.accept(this, null);
return new FunctionTypeVariable(type.index, bound);
}
DartType visitFunctionType(FunctionType type, _) {
var returnType = type.returnType.accept(this, null);
var parameterTypes = _visitList(type.parameterTypes);
var optionalParameterTypes = _visitList(type.optionalParameterTypes);
var namedParameterTypes = _visitList(type.namedParameterTypes);
var typeVariables = type.typeVariables
.map<FunctionTypeVariable>((t) => t.accept<DartType, Null>(this, null))
.toList();
var typedefType = type.typedefType?.accept(this, null);
return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
type.namedParameters, namedParameterTypes, typeVariables, typedefType);
}
DartType visitInterfaceType(InterfaceType type, _) {
var element = toBackendEntity(type.element);
var args = _visitList(type.typeArguments);
return new InterfaceType(element, args);
}
DartType visitTypedefType(TypedefType type, _) {
var element = toBackendEntity(type.element);
var args = _visitList(type.typeArguments);
return new TypedefType(element, args);
}
List<DartType> _visitList(List<DartType> list) =>
list.map<DartType>((t) => t.accept(this, null)).toList();
}

View file

@ -0,0 +1,11 @@
// 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.
import '../libs/deferred_typed_map_lib1.dart' deferred as lib;
/*element: main:OutputUnit(main, {})*/
main() async {
await lib.loadLibrary();
print(lib.table[1]);
}

View file

@ -139,7 +139,7 @@ void computeKernelOutputUnitData(
SourceSpan span = computeSourceSpanFromTreeNode(node);
if (node is ir.ConstructorInvocation ||
node is ir.ListLiteral ||
node is ir.MapLiteral) {
(node is ir.MapLiteral && node.keyType == null)) {
// Adjust the source-span to match the AST-based location. The kernel FE
// skips the "const" keyword for the expression offset and any prefix in
// front of the constructor. The "-6" is an approximation assuming that

View file

@ -0,0 +1,19 @@
// 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.
class M {}
typedef dynamic FF({M b});
/*element: table:OutputUnit(1, {lib})*/
const table =
/*ast.null*/
/*kernel.OutputUnit(1, {lib})*/
const <int, FF>{1: f1, 2: f2};
/*element: f1:OutputUnit(1, {lib})*/
dynamic f1({M b}) => null;
/*element: f2:OutputUnit(1, {lib})*/
dynamic f2({M b}) => null;