Skip to content

Commit ddff459

Browse files
chloestefantsovaCommit Bot
authored and
Commit Bot
committed
[cfe] Add RecordType, RecordLiteral, and associated nodes
TEST=Covered by upcoming language and co19 tests. Change-Id: Ibe8ecfb7f854adce5646125f6909066e27424665 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256066 Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Stephen Adams <[email protected]> Reviewed-by: Nicholas Shahan <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]> Reviewed-by: Alexander Markov <[email protected]>
1 parent 55307a3 commit ddff459

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1986
-8
lines changed

pkg/compiler/lib/src/inferrer/builder.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,11 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation>
725725
});
726726
}
727727

728+
@override
729+
TypeInformation visitRecordLiteral(ir.RecordLiteral node) {
730+
return defaultExpression(node);
731+
}
732+
728733
@override
729734
TypeInformation visitReturnStatement(ir.ReturnStatement node) {
730735
ir.Node expression = node.expression;
@@ -2322,6 +2327,11 @@ class TypeInformationConstantVisitor
23222327
isConst: true);
23232328
}
23242329

2330+
@override
2331+
TypeInformation visitRecordConstant(ir.RecordConstant node) {
2332+
return defaultConstant(node);
2333+
}
2334+
23252335
@override
23262336
TypeInformation visitInstanceConstant(ir.InstanceConstant node) {
23272337
node.fieldValues.forEach((ir.Reference reference, ir.Constant value) {

pkg/compiler/lib/src/ir/impact.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@ class ConstantImpactVisitor extends ir.VisitOnceConstantVisitor {
300300
}
301301
}
302302

303+
@override
304+
void visitRecordConstant(ir.RecordConstant node) {
305+
return defaultConstant(node);
306+
}
307+
303308
@override
304309
void visitSymbolConstant(ir.SymbolConstant node) {
305310
// TODO(johnniwinther): Handle the library reference.

pkg/compiler/lib/src/ir/util.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,15 @@ class _FreeVariableVisitor implements ir.DartTypeVisitor<bool> {
209209
return false;
210210
}
211211

212+
@override
213+
bool visitRecordType(ir.RecordType node) {
214+
if (visitList(node.positional)) return true;
215+
for (ir.NamedType namedType in node.named) {
216+
if (visit(namedType.type)) return true;
217+
}
218+
return false;
219+
}
220+
212221
@override
213222
bool visitInterfaceType(ir.InterfaceType node) {
214223
return visitList(node.typeArguments);

pkg/compiler/lib/src/ir/visitors.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ class ConstantValuefier extends ir.ComputeOnceConstantVisitor<ConstantValue> {
296296
elementMap.commonElements, type, keys, values);
297297
}
298298

299+
@override
300+
ConstantValue visitRecordConstant(ir.RecordConstant node) {
301+
return defaultConstant(node);
302+
}
303+
299304
@override
300305
ConstantValue visitSymbolConstant(ir.SymbolConstant node) {
301306
return constant_system.createSymbol(elementMap.commonElements, node.name);

pkg/compiler/lib/src/serialization/node_indexer.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,18 @@ class ConstantNodeIndexerVisitor implements ir.ConstantVisitor<void> {
354354
}
355355
}
356356

357+
@override
358+
void visitRecordConstant(ir.RecordConstant node) {
359+
if (_register(node)) {
360+
for (ir.Constant field in node.positional) {
361+
field.accept(this);
362+
}
363+
for (ir.ConstantRecordNamedField namedField in node.named) {
364+
namedField.value.accept(this);
365+
}
366+
}
367+
}
368+
357369
@override
358370
void visitSymbolConstant(ir.SymbolConstant node) {
359371
_register(node);

pkg/compiler/test/helpers/ir_types.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,27 @@ class TypeTextVisitor implements ir.DartTypeVisitor1<void, StringBuffer> {
9696
sb.write(')');
9797
}
9898

99+
@override
100+
void visitRecordType(ir.RecordType node, StringBuffer sb) {
101+
sb.write('Record');
102+
sb.write('(');
103+
_writeTypes(node.positional, sb);
104+
if (node.named.isNotEmpty) {
105+
if (node.positional.isNotEmpty) {
106+
sb.write(',');
107+
}
108+
String comma = '';
109+
for (ir.NamedType namedType in node.named) {
110+
sb.write(comma);
111+
sb.write(namedType.name);
112+
sb.write(': ');
113+
writeType(namedType.type, sb);
114+
comma = ',';
115+
}
116+
}
117+
sb.write(')');
118+
}
119+
99120
@override
100121
void visitInterfaceType(ir.InterfaceType node, StringBuffer sb) {
101122
sb.write(node.classNode.name);

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,6 +3188,9 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
31883188
: typeRep;
31893189
}
31903190

3191+
@override
3192+
js_ast.Expression visitRecordType(type) => defaultDartType(type);
3193+
31913194
/// Emits an expression that lets you access statics on a [type] from code.
31923195
js_ast.Expression _emitConstructorAccess(InterfaceType type) {
31933196
return _emitJSInterop(type.classNode) ??
@@ -4637,6 +4640,16 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
46374640
node.receiver, node.interfaceTarget, node.name.text);
46384641
}
46394642

4643+
@override
4644+
js_ast.Expression visitRecordIndexGet(RecordIndexGet node) {
4645+
return defaultExpression(node);
4646+
}
4647+
4648+
@override
4649+
js_ast.Expression visitRecordNameGet(RecordNameGet node) {
4650+
return defaultExpression(node);
4651+
}
4652+
46404653
@override
46414654
js_ast.Expression visitInstanceTearOff(InstanceTearOff node) {
46424655
return _emitPropertyGet(
@@ -6315,6 +6328,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
63156328
[_emitType(keyType), _emitType(valueType), entries]));
63166329
}
63176330

6331+
@override
6332+
js_ast.Expression visitRecordLiteral(RecordLiteral node) =>
6333+
defaultExpression(node);
6334+
63186335
@override
63196336
js_ast.Expression visitAwaitExpression(AwaitExpression node) =>
63206337
js_ast.Yield(_visitExpression(node.operand));
@@ -6645,6 +6662,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
66456662
js_ast.Expression visitSetConstant(SetConstant node) => _emitConstSet(
66466663
node.typeArgument, node.entries.map(visitConstant).toList());
66476664

6665+
@override
6666+
js_ast.Expression visitRecordConstant(RecordConstant node) =>
6667+
defaultConstant(node);
6668+
66486669
@override
66496670
js_ast.Expression visitInstanceConstant(InstanceConstant node) {
66506671
_declareBeforeUse(node.classNode);

pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,82 @@ Message _withArgumentsConstEvalInvalidPropertyGet(
657657
arguments: {'stringOKEmpty': stringOKEmpty, 'constant': _constant});
658658
}
659659

660+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
661+
const Template<
662+
Message Function(String stringOKEmpty, Constant _constant,
663+
bool isNonNullableByDefault)>
664+
templateConstEvalInvalidRecordIndexGet = const Template<
665+
Message Function(
666+
String stringOKEmpty,
667+
Constant _constant,
668+
bool
669+
isNonNullableByDefault)>(
670+
problemMessageTemplate:
671+
r"""The property '#stringOKEmpty' can't be accessed on '#constant' in a constant expression.""",
672+
withArguments: _withArgumentsConstEvalInvalidRecordIndexGet);
673+
674+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
675+
const Code<
676+
Message Function(String stringOKEmpty, Constant _constant,
677+
bool isNonNullableByDefault)> codeConstEvalInvalidRecordIndexGet =
678+
const Code<
679+
Message Function(String stringOKEmpty, Constant _constant,
680+
bool isNonNullableByDefault)>("ConstEvalInvalidRecordIndexGet",
681+
analyzerCodes: <String>["CONST_EVAL_THROWS_EXCEPTION"]);
682+
683+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
684+
Message _withArgumentsConstEvalInvalidRecordIndexGet(
685+
String stringOKEmpty, Constant _constant, bool isNonNullableByDefault) {
686+
// ignore: unnecessary_null_comparison
687+
if (stringOKEmpty == null || stringOKEmpty.isEmpty) stringOKEmpty = '(empty)';
688+
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
689+
List<Object> constantParts = labeler.labelConstant(_constant);
690+
String constant = constantParts.join();
691+
return new Message(codeConstEvalInvalidRecordIndexGet,
692+
problemMessage:
693+
"""The property '${stringOKEmpty}' can't be accessed on '${constant}' in a constant expression.""" +
694+
labeler.originMessages,
695+
arguments: {'stringOKEmpty': stringOKEmpty, 'constant': _constant});
696+
}
697+
698+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
699+
const Template<
700+
Message Function(String stringOKEmpty, Constant _constant,
701+
bool isNonNullableByDefault)>
702+
templateConstEvalInvalidRecordNameGet = const Template<
703+
Message Function(
704+
String stringOKEmpty,
705+
Constant _constant,
706+
bool
707+
isNonNullableByDefault)>(
708+
problemMessageTemplate:
709+
r"""The property '#stringOKEmpty' can't be accessed on '#constant' in a constant expression.""",
710+
withArguments: _withArgumentsConstEvalInvalidRecordNameGet);
711+
712+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
713+
const Code<
714+
Message Function(String stringOKEmpty, Constant _constant,
715+
bool isNonNullableByDefault)> codeConstEvalInvalidRecordNameGet =
716+
const Code<
717+
Message Function(String stringOKEmpty, Constant _constant,
718+
bool isNonNullableByDefault)>("ConstEvalInvalidRecordNameGet",
719+
analyzerCodes: <String>["CONST_EVAL_THROWS_EXCEPTION"]);
720+
721+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
722+
Message _withArgumentsConstEvalInvalidRecordNameGet(
723+
String stringOKEmpty, Constant _constant, bool isNonNullableByDefault) {
724+
// ignore: unnecessary_null_comparison
725+
if (stringOKEmpty == null || stringOKEmpty.isEmpty) stringOKEmpty = '(empty)';
726+
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
727+
List<Object> constantParts = labeler.labelConstant(_constant);
728+
String constant = constantParts.join();
729+
return new Message(codeConstEvalInvalidRecordNameGet,
730+
problemMessage:
731+
"""The property '${stringOKEmpty}' can't be accessed on '${constant}' in a constant expression.""" +
732+
labeler.originMessages,
733+
arguments: {'stringOKEmpty': stringOKEmpty, 'constant': _constant});
734+
}
735+
660736
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
661737
const Template<
662738
Message Function(Constant _constant, bool isNonNullableByDefault)>
@@ -1843,6 +1919,45 @@ Message _withArgumentsIncorrectTypeArgumentQualifiedInferred(
18431919
});
18441920
}
18451921

1922+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1923+
const Template<
1924+
Message Function(int count, int count2, DartType _type,
1925+
bool isNonNullableByDefault)>
1926+
templateIndexOutOfBoundInRecordIndexGet =
1927+
const Template<
1928+
Message Function(int count, int count2, DartType _type,
1929+
bool isNonNullableByDefault)>(
1930+
problemMessageTemplate:
1931+
r"""Index #count is out of range 0..#count2 of positional fields of records #type.""",
1932+
withArguments: _withArgumentsIndexOutOfBoundInRecordIndexGet);
1933+
1934+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1935+
const Code<
1936+
Message Function(
1937+
int count, int count2, DartType _type, bool isNonNullableByDefault)>
1938+
codeIndexOutOfBoundInRecordIndexGet = const Code<
1939+
Message Function(int count, int count2, DartType _type,
1940+
bool isNonNullableByDefault)>(
1941+
"IndexOutOfBoundInRecordIndexGet",
1942+
);
1943+
1944+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1945+
Message _withArgumentsIndexOutOfBoundInRecordIndexGet(
1946+
int count, int count2, DartType _type, bool isNonNullableByDefault) {
1947+
// ignore: unnecessary_null_comparison
1948+
if (count == null) throw 'No count provided';
1949+
// ignore: unnecessary_null_comparison
1950+
if (count2 == null) throw 'No count provided';
1951+
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
1952+
List<Object> typeParts = labeler.labelType(_type);
1953+
String type = typeParts.join();
1954+
return new Message(codeIndexOutOfBoundInRecordIndexGet,
1955+
problemMessage:
1956+
"""Index ${count} is out of range 0..${count2} of positional fields of records ${type}.""" +
1957+
labeler.originMessages,
1958+
arguments: {'count': count, 'count2': count2, 'type': _type});
1959+
}
1960+
18461961
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
18471962
const Template<
18481963
Message Function(
@@ -3690,6 +3805,41 @@ Message _withArgumentsMixinInferenceNoMatchingClass(
36903805
arguments: {'name': name, 'name2': name2, 'type': _type});
36913806
}
36923807

3808+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3809+
const Template<
3810+
Message Function(
3811+
String string, DartType _type, bool isNonNullableByDefault)>
3812+
templateNameNotFoundInRecordNameGet = const Template<
3813+
Message Function(
3814+
String string, DartType _type, bool isNonNullableByDefault)>(
3815+
problemMessageTemplate:
3816+
r"""Field name #string isn't found in records of type #type.""",
3817+
withArguments: _withArgumentsNameNotFoundInRecordNameGet);
3818+
3819+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3820+
const Code<
3821+
Message Function(
3822+
String string, DartType _type, bool isNonNullableByDefault)>
3823+
codeNameNotFoundInRecordNameGet = const Code<
3824+
Message Function(
3825+
String string, DartType _type, bool isNonNullableByDefault)>(
3826+
"NameNotFoundInRecordNameGet",
3827+
);
3828+
3829+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3830+
Message _withArgumentsNameNotFoundInRecordNameGet(
3831+
String string, DartType _type, bool isNonNullableByDefault) {
3832+
if (string.isEmpty) throw 'No string provided';
3833+
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
3834+
List<Object> typeParts = labeler.labelType(_type);
3835+
String type = typeParts.join();
3836+
return new Message(codeNameNotFoundInRecordNameGet,
3837+
problemMessage:
3838+
"""Field name ${string} isn't found in records of type ${type}.""" +
3839+
labeler.originMessages,
3840+
arguments: {'string': string, 'type': _type});
3841+
}
3842+
36933843
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
36943844
const Template<Message Function(DartType _type, bool isNonNullableByDefault)>
36953845
templateNonNullAwareSpreadIsNull = const Template<

0 commit comments

Comments
 (0)