mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 16:35:01 +00:00
Extension types. Report when implemented extension type representation is not a supertype of the declared extention type.
Change-Id: Iebb19c3f57046db600305993cc69dae04946889d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319861 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
acefe9ab6d
commit
53cccf9c8b
|
@ -656,6 +656,8 @@ CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_ITSELF:
|
|||
status: noFix
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_NOT_SUPERTYPE_OF_ERASURE:
|
||||
status: noFix
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE:
|
||||
status: noFix
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT:
|
||||
status: noFix
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF:
|
||||
|
|
|
@ -1780,17 +1780,39 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (type.element is! ExtensionTypeElement) {
|
||||
final erasure = declaredElement.typeErasure;
|
||||
if (!typeSystem.isSubtypeOf(erasure, type)) {
|
||||
_errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode
|
||||
.EXTENSION_TYPE_IMPLEMENTS_NOT_SUPERTYPE_OF_ERASURE,
|
||||
node,
|
||||
[type, erasure],
|
||||
);
|
||||
// When `type` is an extension type.
|
||||
if (type is InterfaceTypeImpl) {
|
||||
final implementedRepresentation = type.representationType;
|
||||
if (implementedRepresentation != null) {
|
||||
final declaredRepresentation = declaredElement.representation.type;
|
||||
if (!typeSystem.isSubtypeOf(
|
||||
declaredRepresentation,
|
||||
implementedRepresentation,
|
||||
)) {
|
||||
_errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode
|
||||
.EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE,
|
||||
node,
|
||||
[
|
||||
implementedRepresentation,
|
||||
type.element.name,
|
||||
declaredRepresentation,
|
||||
declaredElement.name,
|
||||
],
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final erasure = declaredElement.typeErasure;
|
||||
if (!typeSystem.isSubtypeOf(erasure, type)) {
|
||||
_errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_NOT_SUPERTYPE_OF_ERASURE,
|
||||
node,
|
||||
[type, erasure],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _visitIf(IfElementOrStatementImpl node) {
|
||||
|
|
|
@ -1663,6 +1663,21 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
|
|||
"Try specifying a different type, or remove the type from the list.",
|
||||
);
|
||||
|
||||
/// Parameters:
|
||||
/// 0: the representation type of the implemented extension type
|
||||
/// 1: the name of the implemented extension type
|
||||
/// 2: the representation type of the this extension type
|
||||
/// 3: the name of the this extension type
|
||||
static const CompileTimeErrorCode
|
||||
EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE =
|
||||
CompileTimeErrorCode(
|
||||
'EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE',
|
||||
"'{0}', the representation type of '{1}', is not a supertype of '{2}', the "
|
||||
"representation type of '{3}'.",
|
||||
correctionMessage:
|
||||
"Try specifying a different type, or remove the type from the list.",
|
||||
);
|
||||
|
||||
/// Parameters:
|
||||
/// 0: the name of the extension type
|
||||
/// 1: the name of the conflicting member
|
||||
|
|
|
@ -198,6 +198,7 @@ const List<ErrorCode> errorCodeValues = [
|
|||
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_DISALLOWED_TYPE,
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_ITSELF,
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_NOT_SUPERTYPE_OF_ERASURE,
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE,
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT,
|
||||
CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF,
|
||||
CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER,
|
||||
|
|
|
@ -5090,6 +5090,15 @@ CompileTimeErrorCode:
|
|||
Parameters:
|
||||
0: the implemented not extension type
|
||||
1: the ultimate representation type
|
||||
EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE:
|
||||
problemMessage: "'{0}', the representation type of '{1}', is not a supertype of '{2}', the representation type of '{3}'."
|
||||
correctionMessage: Try specifying a different type, or remove the type from the list.
|
||||
comment: |-
|
||||
Parameters:
|
||||
0: the representation type of the implemented extension type
|
||||
1: the name of the implemented extension type
|
||||
2: the representation type of the this extension type
|
||||
3: the name of the this extension type
|
||||
EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT:
|
||||
problemMessage: "The extension type '{0}' has more than one distinct member named '{1}' from implemented types."
|
||||
correctionMessage: Try redeclaring the corresponding member in this extension type.
|
||||
|
|
|
@ -9,12 +9,12 @@ import '../dart/resolution/context_collection_resolution.dart';
|
|||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(ExtensionTypeImplementsDisallowedTypeTest);
|
||||
defineReflectiveTests(ExtensionTypeImplementsNotSupertypeOfErasureTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ExtensionTypeImplementsDisallowedTypeTest
|
||||
class ExtensionTypeImplementsNotSupertypeOfErasureTest
|
||||
extends PubPackageResolutionTest {
|
||||
test_notSupertype() async {
|
||||
await assertErrorsInCode('''
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) 2023, 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 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(
|
||||
ExtensionTypeImplementsRepresentationNotSupertypeTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ExtensionTypeImplementsRepresentationNotSupertypeTest
|
||||
extends PubPackageResolutionTest {
|
||||
test_notSupertype() async {
|
||||
await assertErrorsInCode('''
|
||||
extension type A(String it) {}
|
||||
extension type B(int it) implements A {}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode
|
||||
.EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE,
|
||||
67,
|
||||
1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_supertype() async {
|
||||
await assertNoErrorsInCode('''
|
||||
extension type A(num it) {}
|
||||
extension type B(int it) implements A {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_supertype2() async {
|
||||
await assertNoErrorsInCode('''
|
||||
extension type A(S1 it) {}
|
||||
extension type B(S3 it) implements A {}
|
||||
class S1 {}
|
||||
class S2 extends S1 {}
|
||||
class S3 extends S2 {}
|
||||
''');
|
||||
}
|
||||
}
|
|
@ -252,6 +252,8 @@ import 'extension_type_implements_itself_test.dart'
|
|||
as extension_type_implements_itself;
|
||||
import 'extension_type_implements_not_supertype_of_erasure_test.dart'
|
||||
as extension_type_implements_not_supertype_of_erasure;
|
||||
import 'extension_type_implements_representation_not_supertype_test.dart'
|
||||
as extension_type_implements_representation_not_supertype;
|
||||
import 'extension_type_inherited_member_conflict_test.dart'
|
||||
as extension_type_inherited_member_conflict;
|
||||
import 'extension_type_representation_depends_on_itself_test.dart'
|
||||
|
@ -1061,6 +1063,7 @@ main() {
|
|||
extension_type_implements_disallowed_type.main();
|
||||
extension_type_implements_itself.main();
|
||||
extension_type_implements_not_supertype_of_erasure.main();
|
||||
extension_type_implements_representation_not_supertype.main();
|
||||
extension_type_inherited_member_conflict.main();
|
||||
extension_type_representation_depends_on_itself.main();
|
||||
external_field_constructor_initializer.main();
|
||||
|
|
Loading…
Reference in a new issue