Skip to content

Commit 9713ce1

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Report EXTENSION_CONFLICTING_STATIC_AND_INSTANCE and DUPLICATE_DEFINITION for extensions.
[email protected] Change-Id: I237ee3edc6a2196693638c12c59d1530a1f15152 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112605 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent a244295 commit 9713ce1

File tree

7 files changed

+381
-4
lines changed

7 files changed

+381
-4
lines changed

pkg/analyzer/lib/error/error.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ const List<ErrorCode> errorCodeValues = const [
137137
CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS,
138138
CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
139139
CompileTimeErrorCode.EXTENDS_NON_CLASS,
140+
CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
140141
CompileTimeErrorCode.EXTENSION_DECLARES_ABSTRACT_MEMBER,
141142
CompileTimeErrorCode.EXTENSION_DECLARES_CONSTRUCTOR,
142143
CompileTimeErrorCode.EXTENSION_DECLARES_INSTANCE_FIELD,

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,22 @@ class CompileTimeErrorCode extends ErrorCode {
12681268
correction: "Try specifying a different superclass, or "
12691269
"removing the extends clause.");
12701270

1271+
/**
1272+
* It is for an extension to define a static member and an instance member
1273+
* with the same base name.
1274+
*
1275+
* Parameters:
1276+
* 0: the name of the extension defining the conflicting member
1277+
* 1: the name of the conflicting static member
1278+
*/
1279+
static const CompileTimeErrorCode EXTENSION_CONFLICTING_STATIC_AND_INSTANCE =
1280+
const CompileTimeErrorCode(
1281+
'EXTENSION_CONFLICTING_STATIC_AND_INSTANCE',
1282+
"Extension '{0}' can't define static member '{1}' and instance "
1283+
"member with the same name.",
1284+
correction:
1285+
"Try renaming the member to a name that doesn't conflict.");
1286+
12711287
/**
12721288
* No parameters.
12731289
*/

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
726726
@override
727727
void visitExtensionDeclaration(ExtensionDeclaration node) {
728728
_enclosingExtension = node.declaredElement;
729+
_checkDuplicateExtensionMembers(node.members);
729730
super.visitExtensionDeclaration(node);
730731
_enclosingExtension = null;
731732
}
@@ -1739,6 +1740,44 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
17391740
}
17401741
}
17411742

1743+
/**
1744+
* Check that there are no members with the same name.
1745+
*/
1746+
void _checkDuplicateExtensionMembers(List<ClassMember> members) {
1747+
var instanceGetters = <String, Element>{};
1748+
var instanceSetters = <String, Element>{};
1749+
var staticGetters = <String, Element>{};
1750+
var staticSetters = <String, Element>{};
1751+
1752+
for (var member in members) {
1753+
if (member is MethodDeclaration) {
1754+
_checkDuplicateIdentifier(
1755+
member.isStatic ? staticGetters : instanceGetters,
1756+
member.name,
1757+
setterScope: member.isStatic ? staticSetters : instanceSetters,
1758+
);
1759+
}
1760+
}
1761+
1762+
// Check for local static members conflicting with local instance members.
1763+
for (var member in members) {
1764+
if (member is MethodDeclaration) {
1765+
if (member.isStatic) {
1766+
var identifier = member.name;
1767+
var name = identifier.name;
1768+
if (instanceGetters.containsKey(name) ||
1769+
instanceSetters.containsKey(name)) {
1770+
_errorReporter.reportErrorForNode(
1771+
CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
1772+
identifier,
1773+
[_enclosingExtension.name, name],
1774+
);
1775+
}
1776+
}
1777+
}
1778+
}
1779+
}
1780+
17421781
/**
17431782
* Check whether the given [element] defined by the [identifier] is already
17441783
* in one of the scopes - [getterScope] or [setterScope], and produce an
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// Copyright (c) 2019, 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/dart/analysis/features.dart';
6+
import 'package:analyzer/src/error/codes.dart';
7+
import 'package:analyzer/src/generated/engine.dart';
8+
import 'package:test_reflective_loader/test_reflective_loader.dart';
9+
10+
import '../dart/resolution/driver_resolution.dart';
11+
12+
main() {
13+
defineReflectiveSuite(() {
14+
defineReflectiveTests(DuplicateDefinitionExtensionTest);
15+
});
16+
}
17+
18+
@reflectiveTest
19+
class DuplicateDefinitionExtensionTest extends DriverResolutionTest {
20+
@override
21+
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
22+
..contextFeatures = new FeatureSet.forTesting(
23+
sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
24+
25+
CompileTimeErrorCode get _errorCode =>
26+
CompileTimeErrorCode.DUPLICATE_DEFINITION;
27+
28+
test_extendedType_instance() async {
29+
await assertNoErrorsInCode('''
30+
class A {
31+
int get foo => 0;
32+
set foo(_) {}
33+
void bar() {}
34+
}
35+
36+
extension E on A {
37+
int get foo => 0;
38+
set foo(_) {}
39+
void bar() {}
40+
}
41+
''');
42+
}
43+
44+
test_extendedType_static() async {
45+
await assertNoErrorsInCode('''
46+
class A {
47+
static int get foo => 0;
48+
static set foo(_) {}
49+
static void bar() {}
50+
}
51+
52+
extension E on A {
53+
static int get foo => 0;
54+
static set foo(_) {}
55+
static void bar() {}
56+
}
57+
''');
58+
}
59+
60+
test_instance_getter_getter() async {
61+
await assertErrorsInCode('''
62+
extension E on String {
63+
int get foo => 0;
64+
int get foo => 0;
65+
}
66+
''', [
67+
error(_errorCode, 54, 3),
68+
]);
69+
}
70+
71+
test_instance_getter_setter() async {
72+
await assertNoErrorsInCode('''
73+
extension E on String {
74+
int get foo => 0;
75+
set foo(_) {}
76+
}
77+
''');
78+
}
79+
80+
test_instance_method_method() async {
81+
await assertErrorsInCode('''
82+
extension E on String {
83+
void foo() {}
84+
void foo() {}
85+
}
86+
''', [
87+
error(_errorCode, 47, 3),
88+
]);
89+
}
90+
91+
test_instance_setter_setter() async {
92+
await assertErrorsInCode('''
93+
extension E on String {
94+
set foo(_) {}
95+
set foo(_) {}
96+
}
97+
''', [
98+
error(_errorCode, 46, 3),
99+
]);
100+
}
101+
102+
test_static_getter_getter() async {
103+
await assertErrorsInCode('''
104+
extension E on String {
105+
static int get foo => 0;
106+
static int get foo => 0;
107+
}
108+
''', [
109+
error(_errorCode, 68, 3),
110+
]);
111+
}
112+
113+
test_static_getter_setter() async {
114+
await assertNoErrorsInCode('''
115+
extension E on String {
116+
static int get foo => 0;
117+
static set foo(_) {}
118+
}
119+
''');
120+
}
121+
122+
test_static_method_method() async {
123+
await assertErrorsInCode('''
124+
extension E on String {
125+
static void foo() {}
126+
static void foo() {}
127+
}
128+
''', [
129+
error(_errorCode, 61, 3),
130+
]);
131+
}
132+
133+
test_static_setter_setter() async {
134+
await assertErrorsInCode('''
135+
extension E on String {
136+
static set foo(_) {}
137+
static set foo(_) {}
138+
}
139+
''', [
140+
error(_errorCode, 60, 3),
141+
]);
142+
}
143+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// Copyright (c) 2019, 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/dart/analysis/features.dart';
6+
import 'package:analyzer/src/error/codes.dart';
7+
import 'package:analyzer/src/generated/engine.dart';
8+
import 'package:test_reflective_loader/test_reflective_loader.dart';
9+
10+
import '../dart/resolution/driver_resolution.dart';
11+
12+
main() {
13+
defineReflectiveSuite(() {
14+
defineReflectiveTests(ExtensionConflictingStaticAndInstanceTest);
15+
});
16+
}
17+
18+
@reflectiveTest
19+
class ExtensionConflictingStaticAndInstanceTest extends DriverResolutionTest {
20+
@override
21+
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
22+
..contextFeatures = new FeatureSet.forTesting(
23+
sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
24+
25+
CompileTimeErrorCode get _errorCode =>
26+
CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE;
27+
28+
test_extendedType_getter() async {
29+
await assertNoErrorsInCode('''
30+
class A {
31+
static int get foo => 0;
32+
int get bar => 0;
33+
}
34+
35+
extension E on A {
36+
int get foo => 0;
37+
static int get bar => 0;
38+
}
39+
''');
40+
}
41+
42+
test_extendedType_method() async {
43+
await assertNoErrorsInCode('''
44+
class A {
45+
static void foo() {}
46+
void bar() {}
47+
}
48+
49+
extension E on A {
50+
void foo() {}
51+
static void bar() {}
52+
}
53+
''');
54+
}
55+
56+
test_extendedType_setter() async {
57+
await assertNoErrorsInCode('''
58+
class A {
59+
static set foo(_) {}
60+
set bar(_) {}
61+
}
62+
63+
extension E on A {
64+
set foo(_) {}
65+
static set bar(_) {}
66+
}
67+
''');
68+
}
69+
70+
test_getter_getter() async {
71+
await assertErrorsInCode('''
72+
extension E on String {
73+
static int get foo => 0;
74+
int get foo => 0;
75+
}
76+
''', [
77+
error(_errorCode, 41, 3),
78+
]);
79+
}
80+
81+
test_getter_method() async {
82+
await assertErrorsInCode('''
83+
extension E on String {
84+
static int get foo => 0;
85+
void foo() {}
86+
}
87+
''', [
88+
error(_errorCode, 41, 3),
89+
]);
90+
}
91+
92+
test_getter_setter() async {
93+
await assertErrorsInCode('''
94+
extension E on String {
95+
static int get foo => 0;
96+
set foo(_) {}
97+
}
98+
''', [
99+
error(_errorCode, 41, 3),
100+
]);
101+
}
102+
103+
test_method_getter() async {
104+
await assertErrorsInCode('''
105+
extension E on String {
106+
static void foo() {}
107+
int get foo => 0;
108+
}
109+
''', [
110+
error(_errorCode, 38, 3),
111+
]);
112+
}
113+
114+
test_method_method() async {
115+
await assertErrorsInCode('''
116+
extension E on String {
117+
static void foo() {}
118+
void foo() {}
119+
}
120+
''', [
121+
error(_errorCode, 38, 3),
122+
]);
123+
}
124+
125+
test_method_setter() async {
126+
await assertErrorsInCode('''
127+
extension E on String {
128+
static void foo() {}
129+
set foo(_) {}
130+
}
131+
''', [
132+
error(_errorCode, 38, 3),
133+
]);
134+
}
135+
136+
test_setter_getter() async {
137+
await assertErrorsInCode('''
138+
extension E on String {
139+
static set foo(_) {}
140+
int get foo => 0;
141+
}
142+
''', [
143+
error(_errorCode, 37, 3),
144+
]);
145+
}
146+
147+
test_setter_method() async {
148+
await assertErrorsInCode('''
149+
extension E on String {
150+
static set foo(_) {}
151+
void foo() {}
152+
}
153+
''', [
154+
error(_errorCode, 37, 3),
155+
]);
156+
}
157+
158+
test_setter_setter() async {
159+
await assertErrorsInCode('''
160+
extension E on String {
161+
static set foo(_) {}
162+
set foo(_) {}
163+
}
164+
''', [
165+
error(_errorCode, 37, 3),
166+
]);
167+
}
168+
}

0 commit comments

Comments
 (0)