mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:21:18 +00:00
[vm/aot] Initial support for records in TFA
This change adds minimal support for RecordType, RecordLiteral, RecordIndexGet, RecordNameGet and RecordConstant kernel nodes to TFA. TFA is *not* yet extended with the ability to infer record types. TEST=language/records/simple Issue: https://github.com/dart-lang/sdk/issues/49719 Change-Id: I7c5eb860c6a5cb263e4d1bb55ad230e5c51f47c2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/259520 Reviewed-by: Slava Egorov <vegorov@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
aa03b81b81
commit
e5f3b0dc0e
|
@ -542,6 +542,8 @@ abstract class Target {
|
|||
Class? concreteConstMapLiteralClass(CoreTypes coreTypes) => null;
|
||||
Class? concreteSetLiteralClass(CoreTypes coreTypes) => null;
|
||||
Class? concreteConstSetLiteralClass(CoreTypes coreTypes) => null;
|
||||
Class? concreteRecordLiteralClass(CoreTypes coreTypes) => null;
|
||||
Class? concreteConstRecordLiteralClass(CoreTypes coreTypes) => null;
|
||||
|
||||
Class? concreteIntLiteralClass(CoreTypes coreTypes, int value) => null;
|
||||
Class? concreteDoubleLiteralClass(CoreTypes coreTypes, double value) => null;
|
||||
|
|
|
@ -34,6 +34,7 @@ class VmTarget extends Target {
|
|||
Class? _internalImmutableLinkedHashSet;
|
||||
Class? _internalLinkedHashMap;
|
||||
Class? _internalLinkedHashSet;
|
||||
Class? _record;
|
||||
Class? _oneByteString;
|
||||
Class? _twoByteString;
|
||||
Class? _smi;
|
||||
|
@ -451,6 +452,15 @@ class VmTarget extends Target {
|
|||
.getClass('dart:collection', '_InternalImmutableLinkedHashSet');
|
||||
}
|
||||
|
||||
@override
|
||||
Class concreteRecordLiteralClass(CoreTypes coreTypes) {
|
||||
return _record ??= coreTypes.index.getClass('dart:core', '_Record');
|
||||
}
|
||||
|
||||
@override
|
||||
Class concreteConstRecordLiteralClass(CoreTypes coreTypes) =>
|
||||
concreteRecordLiteralClass(coreTypes);
|
||||
|
||||
@override
|
||||
Class? concreteIntLiteralClass(CoreTypes coreTypes, int value) {
|
||||
const int bitsPerInt32 = 32;
|
||||
|
|
|
@ -458,6 +458,16 @@ class _ConstantVisitor extends ConstantVisitor<void> {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitRecordConstant(RecordConstant constant) {
|
||||
for (var value in constant.positional) {
|
||||
visit(value);
|
||||
}
|
||||
for (var value in constant.named.values) {
|
||||
visit(value);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitInstanceConstant(InstanceConstant constant) {
|
||||
rta.addAllocatedClass(constant.classNode);
|
||||
|
|
|
@ -1617,6 +1617,34 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
|
|||
return _staticType(node);
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitRecordLiteral(RecordLiteral node) {
|
||||
for (var expr in node.positional) {
|
||||
_visit(expr);
|
||||
}
|
||||
for (var expr in node.named) {
|
||||
_visit(expr.value);
|
||||
}
|
||||
Class? concreteClass =
|
||||
target.concreteRecordLiteralClass(_environment.coreTypes);
|
||||
if (concreteClass != null) {
|
||||
return _entryPointsListener.addAllocatedClass(concreteClass);
|
||||
}
|
||||
return _staticType(node);
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitRecordIndexGet(RecordIndexGet node) {
|
||||
_visit(node.receiver);
|
||||
return _staticType(node);
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitRecordNameGet(RecordNameGet node) {
|
||||
_visit(node.receiver);
|
||||
return _staticType(node);
|
||||
}
|
||||
|
||||
@override
|
||||
TypeExpr visitInstanceInvocation(InstanceInvocation node) {
|
||||
final receiverNode = node.receiver;
|
||||
|
@ -2561,6 +2589,24 @@ class ConstantAllocationCollector extends ConstantVisitor<Type> {
|
|||
return _getStaticType(constant);
|
||||
}
|
||||
|
||||
@override
|
||||
Type visitRecordConstant(RecordConstant constant) {
|
||||
for (var value in constant.positional) {
|
||||
typeFor(value);
|
||||
}
|
||||
for (var value in constant.named.values) {
|
||||
typeFor(value);
|
||||
}
|
||||
Class? concreteClass = summaryCollector.target
|
||||
.concreteConstRecordLiteralClass(
|
||||
summaryCollector._environment.coreTypes);
|
||||
if (concreteClass != null) {
|
||||
return summaryCollector._entryPointsListener
|
||||
.addAllocatedClass(concreteClass);
|
||||
}
|
||||
return _getStaticType(constant);
|
||||
}
|
||||
|
||||
@override
|
||||
Type visitInstanceConstant(InstanceConstant constant) {
|
||||
final resultClass = summaryCollector._entryPointsListener
|
||||
|
|
|
@ -985,11 +985,6 @@ class _TreeShakerTypeVisitor extends RecursiveVisitor {
|
|||
node.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
visitFunctionType(FunctionType node) {
|
||||
node.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
visitTypeParameterType(TypeParameterType node) {
|
||||
final parent = node.parameter.parent;
|
||||
|
@ -1954,6 +1949,16 @@ class _TreeShakerConstantVisitor extends ConstantVisitor<Null> {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitRecordConstant(RecordConstant constant) {
|
||||
for (var value in constant.positional) {
|
||||
analyzeConstant(value);
|
||||
}
|
||||
for (var value in constant.named.values) {
|
||||
analyzeConstant(value);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitInstanceConstant(InstanceConstant constant) {
|
||||
instanceConstants.add(constant);
|
||||
|
|
|
@ -86,6 +86,9 @@ abstract class TypesBuilder {
|
|||
} else if (type is FunctionType) {
|
||||
// TODO(alexmarkov): support function types
|
||||
result = const AnyType();
|
||||
} else if (type is RecordType) {
|
||||
// TODO(dartbug.com/49719): support inference of record types
|
||||
result = const AnyType();
|
||||
} else if (type is FutureOrType) {
|
||||
// TODO(alexmarkov): support FutureOr types
|
||||
result = const AnyType();
|
||||
|
|
Loading…
Reference in a new issue