Skip to content

Commit 39c9473

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Report MIXINS_SUPER_CLASS.
Bug: #42256 Change-Id: I49c70d5a172062fed4d8663d95701ba855effda6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153823 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent d215ab6 commit 39c9473

File tree

6 files changed

+89
-49
lines changed

6 files changed

+89
-49
lines changed

pkg/analyzer/lib/error/error.dart

+1
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ const List<ErrorCode> errorCodeValues = [
240240
CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS,
241241
CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
242242
CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS,
243+
CompileTimeErrorCode.MIXINS_SUPER_CLASS,
243244
CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
244245
CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS,
245246
CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS,

pkg/analyzer/lib/src/error/codes.dart

+12
Original file line numberDiff line numberDiff line change
@@ -4262,6 +4262,18 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
42624262
CompileTimeErrorCode('MIXIN_WITH_NON_CLASS_SUPERCLASS',
42634263
"Mixin can only be applied to class.");
42644264

4265+
/**
4266+
* Technically this is [IMPLEMENTS_SUPER_CLASS].
4267+
* See https://github.com/dart-lang/sdk/issues/25765#issuecomment-307422593
4268+
*
4269+
* Parameters:
4270+
* 0: the name of the class that appears in both "extends" and "with" clauses
4271+
*/
4272+
static const CompileTimeErrorCode MIXINS_SUPER_CLASS = CompileTimeErrorCode(
4273+
'MIXINS_SUPER_CLASS',
4274+
"'{0}' can't be used in both 'extends' and 'with' clauses.",
4275+
correction: "Try removing one of the occurrences.");
4276+
42654277
/**
42664278
* 7.6.1 Generative Constructors: A generative constructor may be redirecting,
42674279
* in which case its only action is to invoke another generative constructor.

pkg/analyzer/lib/src/generated/error_verifier.dart

+39-13
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
12481248
_checkForRepeatedType(implementsClause?.interfaces,
12491249
CompileTimeErrorCode.IMPLEMENTS_REPEATED);
12501250
_checkImplementsSuperClass(implementsClause);
1251+
_checkMixinsSuperClass(withClause);
12511252
_checkMixinInference(node, withClause);
12521253
_checkForMixinWithConflictingPrivateMember(withClause, superclass);
12531254
_checkForConflictingGenerics(node);
@@ -4626,27 +4627,27 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
46264627
}
46274628
}
46284629

4629-
/// Verify that the given class [declaration] does not have the same class in
4630-
/// the 'extends' and 'implements' clauses.
4630+
/// Verify that the current class does not have the same class in the
4631+
/// 'extends' and 'implements' clauses.
46314632
///
46324633
/// See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS].
46334634
void _checkImplementsSuperClass(ImplementsClause implementsClause) {
4634-
// prepare super type
4635-
InterfaceType superType = _enclosingClass.supertype;
4636-
if (superType == null) {
4635+
if (implementsClause == null) {
46374636
return;
46384637
}
4639-
// prepare interfaces
4640-
if (implementsClause == null) {
4638+
4639+
var superElement = _enclosingClass.supertype?.element;
4640+
if (superElement == null) {
46414641
return;
46424642
}
4643-
// check interfaces
4644-
for (TypeName interfaceNode in implementsClause.interfaces) {
4645-
if (interfaceNode.type == superType) {
4643+
4644+
for (var interfaceNode in implementsClause.interfaces) {
4645+
if (interfaceNode.type.element == superElement) {
46464646
_errorReporter.reportErrorForNode(
4647-
CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
4648-
interfaceNode,
4649-
[superType]);
4647+
CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
4648+
interfaceNode,
4649+
[superElement],
4650+
);
46504651
}
46514652
}
46524653
}
@@ -4720,6 +4721,31 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
47204721
}
47214722
}
47224723

4724+
/// Verify that the current class does not have the same class in the
4725+
/// 'extends' and 'with' clauses.
4726+
///
4727+
/// See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS].
4728+
void _checkMixinsSuperClass(WithClause withClause) {
4729+
if (withClause == null) {
4730+
return;
4731+
}
4732+
4733+
var superElement = _enclosingClass.supertype?.element;
4734+
if (superElement == null) {
4735+
return;
4736+
}
4737+
4738+
for (var mixinNode in withClause.mixinTypes) {
4739+
if (mixinNode.type.element == superElement) {
4740+
_errorReporter.reportErrorForNode(
4741+
CompileTimeErrorCode.MIXINS_SUPER_CLASS,
4742+
mixinNode,
4743+
[superElement],
4744+
);
4745+
}
4746+
}
4747+
}
4748+
47234749
void _checkUseOfCovariantInParameters(FormalParameterList node) {
47244750
AstNode parent = node.parent;
47254751
if (_enclosingClass != null &&
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analyzer/src/error/codes.dart';
6+
import 'package:test_reflective_loader/test_reflective_loader.dart';
7+
8+
import '../dart/resolution/driver_resolution.dart';
9+
10+
main() {
11+
defineReflectiveSuite(() {
12+
defineReflectiveTests(MixinsSuperClassTest);
13+
});
14+
}
15+
16+
@reflectiveTest
17+
class MixinsSuperClassTest extends DriverResolutionTest {
18+
test_class() async {
19+
await assertErrorsInCode(r'''
20+
class A {}
21+
class B extends A with A {}
22+
''', [
23+
error(CompileTimeErrorCode.MIXINS_SUPER_CLASS, 34, 1),
24+
]);
25+
}
26+
27+
test_classAlias() async {
28+
await assertErrorsInCode(r'''
29+
class A {}
30+
class B = A with A;
31+
''', [
32+
error(CompileTimeErrorCode.MIXINS_SUPER_CLASS, 28, 1),
33+
]);
34+
}
35+
}

pkg/analyzer/test/src/diagnostics/private_collision_in_mixin_application_test.dart

-36
Original file line numberDiff line numberDiff line change
@@ -147,22 +147,6 @@ class C extends A with B {}
147147
]);
148148
}
149149

150-
test_class_superclassAndMixin_same() async {
151-
newFile('/test/lib/a.dart', content: r'''
152-
class A {
153-
void _foo() {}
154-
}
155-
''');
156-
157-
await assertErrorsInCode('''
158-
import 'a.dart';
159-
160-
class C extends A with A {}
161-
''', [
162-
error(CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION, 41, 1),
163-
]);
164-
}
165-
166150
test_class_superclassAndMixin_sameLibrary() async {
167151
await assertErrorsInCode('''
168152
class A {
@@ -256,26 +240,6 @@ class B {
256240
import 'a.dart';
257241
258242
class C = A with B;
259-
''', [
260-
error(CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION, 35, 1),
261-
]);
262-
}
263-
264-
test_classTypeAlias_superclassAndMixin_same() async {
265-
newFile('/test/lib/a.dart', content: r'''
266-
class A {
267-
void _foo() {}
268-
}
269-
270-
class B {
271-
void _foo() {}
272-
}
273-
''');
274-
275-
await assertErrorsInCode('''
276-
import 'a.dart';
277-
278-
class C = A with A;
279243
''', [
280244
error(CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION, 35, 1),
281245
]);

pkg/analyzer/test/src/diagnostics/test_all.dart

+2
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ import 'mixin_super_class_constraint_non_interface_test.dart'
310310
as mixin_super_class_constraint_non_interface;
311311
import 'mixin_with_non_class_superclass_test.dart'
312312
as mixin_with_non_class_superclass;
313+
import 'mixins_super_class_test.dart' as mixins_super_class;
313314
import 'must_be_a_native_function_type_test.dart'
314315
as must_be_a_native_function_type;
315316
import 'must_be_a_subtype_test.dart' as must_be_a_subtype;
@@ -744,6 +745,7 @@ main() {
744745
mixin_on_sealed_class.main();
745746
mixin_super_class_constraint_non_interface.main();
746747
mixin_with_non_class_superclass.main();
748+
mixins_super_class.main();
747749
must_be_a_native_function_type.main();
748750
must_be_a_subtype.main();
749751
must_be_immutable.main();

0 commit comments

Comments
 (0)