Skip to content

Commit ef10dca

Browse files
johnniwintherCommit Queue
authored and
Commit Queue
committed
[cfe] Check representation vs implemented types
Close #53170 Change-Id: Ib8f85cf54de7f0e34dcdbb3159139ab4e7f677fa Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320822 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]>
1 parent ba1f302 commit ef10dca

39 files changed

+989
-194
lines changed

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

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,6 +2728,107 @@ Message _withArgumentsInvalidCastTopLevelFunction(
27282728
arguments: {'type': _type, 'type2': _type2});
27292729
}
27302730

2731+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2732+
const Template<
2733+
Message Function(DartType _type, String name, DartType _type2,
2734+
DartType _type3, bool isNonNullableByDefault)>
2735+
templateInvalidExtensionTypeSuperExtensionType = const Template<
2736+
Message Function(DartType _type, String name, DartType _type2,
2737+
DartType _type3, bool isNonNullableByDefault)>(
2738+
problemMessageTemplate:
2739+
r"""The representation type '#type' of extension type '#name' must be a subtype of the representation type '#type2' of the implemented extension type '#type3'.""",
2740+
correctionMessageTemplate:
2741+
r"""Try changing the representation type to a subtype of '#type2'.""",
2742+
withArguments: _withArgumentsInvalidExtensionTypeSuperExtensionType);
2743+
2744+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2745+
const Code<
2746+
Message Function(DartType _type, String name, DartType _type2,
2747+
DartType _type3, bool isNonNullableByDefault)>
2748+
codeInvalidExtensionTypeSuperExtensionType = const Code<
2749+
Message Function(DartType _type, String name, DartType _type2,
2750+
DartType _type3, bool isNonNullableByDefault)>(
2751+
"InvalidExtensionTypeSuperExtensionType",
2752+
);
2753+
2754+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2755+
Message _withArgumentsInvalidExtensionTypeSuperExtensionType(
2756+
DartType _type,
2757+
String name,
2758+
DartType _type2,
2759+
DartType _type3,
2760+
bool isNonNullableByDefault) {
2761+
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
2762+
List<Object> typeParts = labeler.labelType(_type);
2763+
if (name.isEmpty) throw 'No name provided';
2764+
name = demangleMixinApplicationName(name);
2765+
List<Object> type2Parts = labeler.labelType(_type2);
2766+
List<Object> type3Parts = labeler.labelType(_type3);
2767+
String type = typeParts.join();
2768+
String type2 = type2Parts.join();
2769+
String type3 = type3Parts.join();
2770+
return new Message(codeInvalidExtensionTypeSuperExtensionType,
2771+
problemMessage:
2772+
"""The representation type '${type}' of extension type '${name}' must be a subtype of the representation type '${type2}' of the implemented extension type '${type3}'.""" +
2773+
labeler.originMessages,
2774+
correctionMessage: """Try changing the representation type to a subtype of '${type2}'.""",
2775+
arguments: {
2776+
'type': _type,
2777+
'name': name,
2778+
'type2': _type2,
2779+
'type3': _type3
2780+
});
2781+
}
2782+
2783+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2784+
const Template<
2785+
Message Function(
2786+
DartType _type,
2787+
DartType _type2,
2788+
String name,
2789+
bool
2790+
isNonNullableByDefault)>
2791+
templateInvalidExtensionTypeSuperInterface = const Template<
2792+
Message Function(
2793+
DartType _type,
2794+
DartType _type2,
2795+
String name,
2796+
bool
2797+
isNonNullableByDefault)>(
2798+
problemMessageTemplate:
2799+
r"""The implemented interface '#type' must be a supertype of the representation type '#type2' of extension type '#name'.""",
2800+
correctionMessageTemplate:
2801+
r"""Try changing the interface type to a supertype of '#type2' or the representation type to a subtype of '#type'.""",
2802+
withArguments: _withArgumentsInvalidExtensionTypeSuperInterface);
2803+
2804+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2805+
const Code<
2806+
Message Function(DartType _type, DartType _type2, String name,
2807+
bool isNonNullableByDefault)>
2808+
codeInvalidExtensionTypeSuperInterface = const Code<
2809+
Message Function(DartType _type, DartType _type2, String name,
2810+
bool isNonNullableByDefault)>(
2811+
"InvalidExtensionTypeSuperInterface",
2812+
);
2813+
2814+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2815+
Message _withArgumentsInvalidExtensionTypeSuperInterface(
2816+
DartType _type, DartType _type2, String name, bool isNonNullableByDefault) {
2817+
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
2818+
List<Object> typeParts = labeler.labelType(_type);
2819+
List<Object> type2Parts = labeler.labelType(_type2);
2820+
if (name.isEmpty) throw 'No name provided';
2821+
name = demangleMixinApplicationName(name);
2822+
String type = typeParts.join();
2823+
String type2 = type2Parts.join();
2824+
return new Message(codeInvalidExtensionTypeSuperInterface,
2825+
problemMessage:
2826+
"""The implemented interface '${type}' must be a supertype of the representation type '${type2}' of extension type '${name}'.""" +
2827+
labeler.originMessages,
2828+
correctionMessage: """Try changing the interface type to a supertype of '${type2}' or the representation type to a subtype of '${type}'.""",
2829+
arguments: {'type': _type, 'type2': _type2, 'name': name});
2830+
}
2831+
27312832
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
27322833
const Template<
27332834
Message Function(DartType _type, String name, DartType _type2,

pkg/front_end/lib/src/fasta/kernel/kernel_target.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,11 @@ class KernelTarget extends TargetImplementation {
464464
sortedSourceExtensionTypeBuilders, objectClassBuilder);
465465

466466
benchmarker?.enterPhase(BenchmarkPhases.outline_checkSupertypes);
467-
loader.checkSupertypes(sortedSourceClassBuilders, objectClass, enumClass,
467+
loader.checkSupertypes(
468+
sortedSourceClassBuilders,
469+
sortedSourceExtensionTypeBuilders,
470+
objectClass,
471+
enumClass,
468472
underscoreEnumClass);
469473

470474
if (macroApplications != null) {

pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import 'package:front_end/src/fasta/builder/record_type_builder.dart';
77
import 'package:front_end/src/fasta/kernel/body_builder_context.dart';
88
import 'package:kernel/ast.dart';
99
import 'package:kernel/class_hierarchy.dart';
10+
import 'package:kernel/core_types.dart';
11+
import 'package:kernel/type_algebra.dart';
12+
import 'package:kernel/type_environment.dart';
1013

1114
import '../../base/common.dart';
1215
import '../builder/builder.dart';
@@ -22,6 +25,7 @@ import '../builder/type_alias_builder.dart';
2225
import '../builder/type_builder.dart';
2326
import '../builder/type_declaration_builder.dart';
2427
import '../builder/type_variable_builder.dart';
28+
import '../kernel/hierarchy/hierarchy_builder.dart';
2529
import '../kernel/kernel_helper.dart';
2630
import '../messages.dart';
2731
import '../problems.dart';
@@ -380,6 +384,47 @@ class SourceExtensionTypeDeclarationBuilder
380384
return false;
381385
}
382386

387+
void checkSupertypes(
388+
CoreTypes coreTypes, ClassHierarchyBuilder hierarchyBuilder) {
389+
if (interfaceBuilders != null) {
390+
for (int i = 0; i < interfaceBuilders!.length; ++i) {
391+
TypeBuilder typeBuilder = interfaceBuilders![i];
392+
DartType interface =
393+
typeBuilder.build(libraryBuilder, TypeUse.superType);
394+
if (interface is InterfaceType) {
395+
if (!hierarchyBuilder.types.isSubtypeOf(declaredRepresentationType,
396+
interface, SubtypeCheckMode.withNullabilities)) {
397+
libraryBuilder.addProblem(
398+
templateInvalidExtensionTypeSuperInterface.withArguments(
399+
interface, declaredRepresentationType, name, true),
400+
typeBuilder.charOffset!,
401+
noLength,
402+
typeBuilder.fileUri);
403+
}
404+
} else if (interface is ExtensionType) {
405+
DartType instantiatedRepresentationType =
406+
Substitution.fromExtensionType(interface).substituteType(interface
407+
.extensionTypeDeclaration.declaredRepresentationType);
408+
if (!hierarchyBuilder.types.isSubtypeOf(
409+
declaredRepresentationType,
410+
instantiatedRepresentationType,
411+
SubtypeCheckMode.withNullabilities)) {
412+
libraryBuilder.addProblem(
413+
templateInvalidExtensionTypeSuperExtensionType.withArguments(
414+
declaredRepresentationType,
415+
name,
416+
instantiatedRepresentationType,
417+
interface,
418+
true),
419+
typeBuilder.charOffset!,
420+
noLength,
421+
typeBuilder.fileUri);
422+
}
423+
}
424+
}
425+
}
426+
}
427+
383428
@override
384429
void buildOutlineExpressions(
385430
ClassHierarchy classHierarchy,
@@ -499,9 +544,9 @@ class SourceExtensionTypeDeclarationBuilder
499544
return null;
500545
}
501546

502-
// TODO(johnniwinther): Implement representationType.
503547
@override
504-
DartType get declaredRepresentationType => throw new UnimplementedError();
548+
DartType get declaredRepresentationType =>
549+
_extensionTypeDeclaration.declaredRepresentationType;
505550

506551
@override
507552
Iterator<T> fullMemberIterator<T extends Builder>() =>

pkg/front_end/lib/src/fasta/source/source_loader.dart

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2627,13 +2627,22 @@ severity: $severity
26272627
ticker.logMs("Computed core types");
26282628
}
26292629

2630-
void checkSupertypes(List<SourceClassBuilder> sourceClasses,
2631-
Class objectClass, Class enumClass, Class underscoreEnumClass) {
2630+
void checkSupertypes(
2631+
List<SourceClassBuilder> sourceClasses,
2632+
List<SourceExtensionTypeDeclarationBuilder>
2633+
sourceExtensionTypeDeclarations,
2634+
Class objectClass,
2635+
Class enumClass,
2636+
Class underscoreEnumClass) {
26322637
for (SourceClassBuilder builder in sourceClasses) {
2633-
if (builder.libraryBuilder.loader == this && !builder.isPatch) {
2634-
builder.checkSupertypes(coreTypes, hierarchyBuilder, objectClass,
2635-
enumClass, underscoreEnumClass, _macroClassBuilder?.cls);
2636-
}
2638+
assert(builder.libraryBuilder.loader == this && !builder.isPatch);
2639+
builder.checkSupertypes(coreTypes, hierarchyBuilder, objectClass,
2640+
enumClass, underscoreEnumClass, _macroClassBuilder?.cls);
2641+
}
2642+
for (SourceExtensionTypeDeclarationBuilder builder
2643+
in sourceExtensionTypeDeclarations) {
2644+
assert(builder.libraryBuilder.loader == this && !builder.isPatch);
2645+
builder.checkSupertypes(coreTypes, hierarchyBuilder);
26372646
}
26382647
ticker.logMs("Checked supertypes");
26392648
}

pkg/front_end/messages.status

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,8 @@ InvalidCastTopLevelFunction/example: Fail
521521
InvalidCatchArguments/example: Fail
522522
InvalidContinueTarget/analyzerCode: Fail
523523
InvalidContinueTarget/example: Fail
524+
InvalidExtensionTypeSuperExtensionType/analyzerCode: Fail
525+
InvalidExtensionTypeSuperInterface/analyzerCode: Fail
524526
InvalidGetterSetterType/analyzerCode: Fail
525527
InvalidGetterSetterTypeBothInheritedField/analyzerCode: Fail
526528
InvalidGetterSetterTypeBothInheritedFieldLegacy/analyzerCode: Fail

pkg/front_end/messages.yaml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7084,6 +7084,21 @@ ExtensionTypeDeclarationCause:
70847084
problemMessage: "The issue arises via this extension type declaration."
70857085
severity: CONTEXT
70867086

7087+
InvalidExtensionTypeSuperInterface:
7088+
problemMessage: "The implemented interface '#type' must be a supertype of the representation type '#type2' of extension type '#name'."
7089+
correctionMessage: "Try changing the interface type to a supertype of '#type2' or the representation type to a subtype of '#type'."
7090+
experiments: inline-class
7091+
script: |
7092+
extension type E(num n) implements int {}
7093+
7094+
InvalidExtensionTypeSuperExtensionType:
7095+
problemMessage: "The representation type '#type' of extension type '#name' must be a subtype of the representation type '#type2' of the implemented extension type '#type3'."
7096+
correctionMessage: "Try changing the representation type to a subtype of '#type2'."
7097+
experiments: inline-class
7098+
script: |
7099+
extension type E1(int i) {}
7100+
extension type E2(num n) implements E1 {}
7101+
70877102
MissingPrimaryConstructor:
70887103
problemMessage: "An extension type declaration must have a primary constructor declaration."
70897104
correctionMessage: "Try adding a primary constructor to the extension type declaration."
@@ -7100,4 +7115,4 @@ MissingPrimaryConstructorParameters:
71007115
analyzerCode: ParserErrorCode.MISSING_PRIMARY_CONSTRUCTOR_PARAMETERS
71017116
experiments: inline-class
71027117
script: |
7103-
extension type E.name {}
7118+
extension type E.name {}

pkg/front_end/parser_testcases/inline_class/extends_with.dart.intertwined.expect

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ parseUnit(extension)
66
parseMetadataStar()
77
listener: beginMetadataStar(extension)
88
listener: endMetadataStar(0)
9-
parseTopLevelKeywordDeclaration(, extension, null, null, null, null, null, Instance of 'DirectiveContext')
9+
parseTopLevelKeywordDeclaration(, extension, null, null, null, null, Instance of 'DirectiveContext')
1010
parseExtension(extension)
1111
listener: beginExtensionDeclarationPrelude(extension)
1212
parseExtensionTypeDeclaration(type, extension, type)
@@ -103,7 +103,7 @@ parseUnit(extension)
103103
parseMetadataStar(})
104104
listener: beginMetadataStar(extension)
105105
listener: endMetadataStar(0)
106-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
106+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
107107
parseExtension(extension)
108108
listener: beginExtensionDeclarationPrelude(extension)
109109
parseExtensionTypeDeclaration(type, extension, type)
@@ -200,7 +200,7 @@ parseUnit(extension)
200200
parseMetadataStar(})
201201
listener: beginMetadataStar(extension)
202202
listener: endMetadataStar(0)
203-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
203+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
204204
parseExtension(extension)
205205
listener: beginExtensionDeclarationPrelude(extension)
206206
parseExtensionTypeDeclaration(type, extension, type)
@@ -309,7 +309,7 @@ parseUnit(extension)
309309
parseMetadataStar(})
310310
listener: beginMetadataStar(extension)
311311
listener: endMetadataStar(0)
312-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
312+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
313313
parseExtension(extension)
314314
listener: beginExtensionDeclarationPrelude(extension)
315315
parseExtensionTypeDeclaration(type, extension, type)
@@ -453,7 +453,7 @@ parseUnit(extension)
453453
parseMetadataStar(})
454454
listener: beginMetadataStar(extension)
455455
listener: endMetadataStar(0)
456-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
456+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
457457
parseExtension(extension)
458458
listener: beginExtensionDeclarationPrelude(extension)
459459
parseExtensionTypeDeclaration(type, extension, type)
@@ -609,7 +609,7 @@ parseUnit(extension)
609609
parseMetadataStar(})
610610
listener: beginMetadataStar(extension)
611611
listener: endMetadataStar(0)
612-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
612+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
613613
parseExtension(extension)
614614
listener: beginExtensionDeclarationPrelude(extension)
615615
parseExtensionTypeDeclaration(type, extension, type)
@@ -727,7 +727,7 @@ parseUnit(extension)
727727
parseMetadataStar(})
728728
listener: beginMetadataStar(extension)
729729
listener: endMetadataStar(0)
730-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
730+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
731731
parseExtension(extension)
732732
listener: beginExtensionDeclarationPrelude(extension)
733733
parseExtensionTypeDeclaration(type, extension, type)
@@ -845,7 +845,7 @@ parseUnit(extension)
845845
parseMetadataStar(})
846846
listener: beginMetadataStar(extension)
847847
listener: endMetadataStar(0)
848-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
848+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
849849
parseExtension(extension)
850850
listener: beginExtensionDeclarationPrelude(extension)
851851
parseExtensionTypeDeclaration(type, extension, type)
@@ -990,7 +990,7 @@ parseUnit(extension)
990990
parseMetadataStar(})
991991
listener: beginMetadataStar(extension)
992992
listener: endMetadataStar(0)
993-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
993+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
994994
parseExtension(extension)
995995
listener: beginExtensionDeclarationPrelude(extension)
996996
parseExtensionTypeDeclaration(type, extension, type)
@@ -1155,7 +1155,7 @@ parseUnit(extension)
11551155
parseMetadataStar(})
11561156
listener: beginMetadataStar(extension)
11571157
listener: endMetadataStar(0)
1158-
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, null, Instance of 'DirectiveContext')
1158+
parseTopLevelKeywordDeclaration(}, extension, null, null, null, null, Instance of 'DirectiveContext')
11591159
parseExtension(extension)
11601160
listener: beginExtensionDeclarationPrelude(extension)
11611161
parseExtensionTypeDeclaration(type, extension, type)

0 commit comments

Comments
 (0)