[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:
Alexander Markov 2022-09-16 18:43:50 +00:00 committed by Commit Bot
parent aa03b81b81
commit e5f3b0dc0e
6 changed files with 81 additions and 5 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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();