Skip to content

Commit 3bf33b6

Browse files
scheglovCommit Queue
authored andcommitted
Augment. Issue 55295. Report AUGMENTATION_WITHOUT_DECLARATION.
Bug: #55295 Change-Id: I50811e1ccd7a2be0e71b18eefa9ecb76ac1aef73 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/359961 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
1 parent dbcf24c commit 3bf33b6

File tree

7 files changed

+298
-10
lines changed

7 files changed

+298
-10
lines changed

pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ CompileTimeErrorCode.ASSIGNMENT_TO_TYPE:
209209
status: noFix
210210
CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT:
211211
status: hasFix
212+
CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION:
213+
status: noFix
212214
CompileTimeErrorCode.AUGMENTATION_WITHOUT_IMPORT:
213215
status: needsFix
214216
notes: |-

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,14 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
214214
hasPublishedDocs: true,
215215
);
216216

217+
static const CompileTimeErrorCode AUGMENTATION_WITHOUT_DECLARATION =
218+
CompileTimeErrorCode(
219+
'AUGMENTATION_WITHOUT_DECLARATION',
220+
"The declaration being augmented doesn't exist.",
221+
correctionMessage:
222+
"Try changing the augmentation to match an existing declaration.",
223+
);
224+
217225
static const CompileTimeErrorCode AUGMENTATION_WITHOUT_IMPORT =
218226
CompileTimeErrorCode(
219227
'AUGMENTATION_WITHOUT_IMPORT',

pkg/analyzer/lib/src/error/error_code_values.g.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ const List<ErrorCode> errorCodeValues = [
6464
CompileTimeErrorCode.ASSIGNMENT_TO_METHOD,
6565
CompileTimeErrorCode.ASSIGNMENT_TO_TYPE,
6666
CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT,
67+
CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION,
6768
CompileTimeErrorCode.AUGMENTATION_WITHOUT_IMPORT,
6869
CompileTimeErrorCode.AUGMENTATION_WITHOUT_LIBRARY,
6970
CompileTimeErrorCode.AWAIT_IN_LATE_LOCAL_VARIABLE_INITIALIZER,

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

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,12 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
439439
void visitClassDeclaration(covariant ClassDeclarationImpl node) {
440440
try {
441441
final element = node.declaredElement!;
442+
443+
_checkAugmentations(
444+
augmentKeyword: node.augmentKeyword,
445+
element: element,
446+
);
447+
442448
final augmented = element.augmented;
443449
if (augmented == null) {
444450
return;
@@ -570,6 +576,10 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
570576
}
571577
_checkForUndefinedConstructorInInitializerImplicit(node);
572578
_checkForReturnInGenerativeConstructor(node);
579+
_checkAugmentations(
580+
augmentKeyword: node.augmentKeyword,
581+
element: element,
582+
);
573583
_reportMacroDiagnostics(element);
574584
super.visitConstructorDeclaration(node);
575585
});
@@ -781,9 +791,13 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
781791
_checkForNonFinalFieldInEnum(node);
782792

783793
for (final field in fields.variables) {
784-
if (field.declaredElement case final FieldElementImpl element) {
785-
_reportMacroDiagnostics(element);
786-
}
794+
var element = field.declaredElement;
795+
element as FieldElementImpl;
796+
_checkAugmentations(
797+
augmentKeyword: node.augmentKeyword,
798+
element: element,
799+
);
800+
_reportMacroDiagnostics(element);
787801
}
788802

789803
super.visitFieldDeclaration(node);
@@ -867,6 +881,10 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
867881
_returnTypeVerifier.verifyReturnType(returnType);
868882
_checkForMainFunction1(node.name, node.declaredElement!);
869883
_checkForMainFunction2(node);
884+
_checkAugmentations(
885+
augmentKeyword: node.augmentKeyword,
886+
element: element,
887+
);
870888
_reportMacroDiagnostics(element);
871889
super.visitFunctionDeclaration(node);
872890
});
@@ -1068,6 +1086,10 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
10681086
_checkForTypeAnnotationDeferredClass(returnType);
10691087
_returnTypeVerifier.verifyReturnType(returnType);
10701088
_checkForWrongTypeParameterVarianceInMethod(node);
1089+
_checkAugmentations(
1090+
augmentKeyword: node.augmentKeyword,
1091+
element: element,
1092+
);
10711093
_reportMacroDiagnostics(element);
10721094
super.visitMethodDeclaration(node);
10731095
});
@@ -1097,6 +1119,12 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
10971119
// TODO(scheglov): Verify for all mixin errors.
10981120
try {
10991121
final element = node.declaredElement!;
1122+
1123+
_checkAugmentations(
1124+
augmentKeyword: node.augmentKeyword,
1125+
element: element,
1126+
);
1127+
11001128
final augmented = element.augmented;
11011129
if (augmented == null) {
11021130
return;
@@ -1425,14 +1453,14 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
14251453
_checkForNotInitializedNonNullableVariable(node.variables, true);
14261454

14271455
for (var variable in node.variables.variables) {
1428-
_checkForMainFunction1(variable.name, variable.declaredElement!);
1429-
}
1430-
1431-
for (final variable in node.variables.variables) {
14321456
var element = variable.declaredElement;
1433-
if (element is TopLevelVariableElementImpl) {
1434-
_reportMacroDiagnostics(element);
1435-
}
1457+
element as TopLevelVariableElementImpl;
1458+
_checkForMainFunction1(variable.name, element);
1459+
_checkAugmentations(
1460+
augmentKeyword: node.augmentKeyword,
1461+
element: element,
1462+
);
1463+
_reportMacroDiagnostics(element);
14361464
}
14371465

14381466
super.visitTopLevelVariableDeclaration(node);
@@ -1507,6 +1535,26 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
15071535
_isInLateLocalVariable.removeLast();
15081536
}
15091537

1538+
void _checkAugmentations<T extends ElementImpl>({
1539+
required Token? augmentKeyword,
1540+
required T element,
1541+
}) {
1542+
if (augmentKeyword == null) {
1543+
return;
1544+
}
1545+
1546+
if (element is AugmentableElement<T>) {
1547+
var augmentationTarget = element.augmentationTarget;
1548+
if (augmentationTarget == null) {
1549+
errorReporter.atToken(
1550+
augmentKeyword,
1551+
CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION,
1552+
);
1553+
return;
1554+
}
1555+
}
1556+
}
1557+
15101558
/// Checks the class for problems with the superclass, mixins, or implemented
15111559
/// interfaces.
15121560
///

pkg/analyzer/messages.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,9 @@ CompileTimeErrorCode:
11091109
}
11101110
}
11111111
```
1112+
AUGMENTATION_WITHOUT_DECLARATION:
1113+
problemMessage: The declaration being augmented doesn't exist.
1114+
correctionMessage: Try changing the augmentation to match an existing declaration.
11121115
AUGMENTATION_WITHOUT_IMPORT:
11131116
problemMessage: The library does not import this augmentation.
11141117
correctionMessage: Try updating the augmented library to import this augmentation.
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
// Copyright (c) 2024, 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/context_collection_resolution.dart';
9+
10+
main() {
11+
defineReflectiveSuite(() {
12+
defineReflectiveTests(AugmentationWithoutDeclarationTest);
13+
});
14+
}
15+
16+
@reflectiveTest
17+
class AugmentationWithoutDeclarationTest extends PubPackageResolutionTest {
18+
test_class() async {
19+
newFile('$testPackageLibPath/a.dart', r'''
20+
import augment 'test.dart';
21+
''');
22+
23+
await assertErrorsInCode(r'''
24+
library augment 'a.dart';
25+
26+
augment class A {}
27+
''', [
28+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 27, 7),
29+
]);
30+
}
31+
32+
test_class_constructor() async {
33+
newFile('$testPackageLibPath/a.dart', r'''
34+
import augment 'test.dart';
35+
36+
class A {}
37+
''');
38+
39+
await assertErrorsInCode(r'''
40+
library augment 'a.dart';
41+
42+
augment class A {
43+
augment A.named();
44+
}
45+
''', [
46+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 47, 7),
47+
]);
48+
}
49+
50+
test_class_field() async {
51+
newFile('$testPackageLibPath/a.dart', r'''
52+
import augment 'test.dart';
53+
54+
class A {}
55+
''');
56+
57+
await assertErrorsInCode(r'''
58+
library augment 'a.dart';
59+
60+
augment class A {
61+
augment int foo = 0;
62+
}
63+
''', [
64+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 47, 7),
65+
]);
66+
}
67+
68+
test_class_getter() async {
69+
newFile('$testPackageLibPath/a.dart', r'''
70+
import augment 'test.dart';
71+
72+
class A {}
73+
''');
74+
75+
await assertErrorsInCode(r'''
76+
library augment 'a.dart';
77+
78+
augment class A {
79+
augment int get foo => 0;
80+
}
81+
''', [
82+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 47, 7),
83+
]);
84+
}
85+
86+
test_class_method() async {
87+
newFile('$testPackageLibPath/a.dart', r'''
88+
import augment 'test.dart';
89+
90+
class A {}
91+
''');
92+
93+
await assertErrorsInCode(r'''
94+
library augment 'a.dart';
95+
96+
augment class A {
97+
augment void foo() {}
98+
}
99+
''', [
100+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 47, 7),
101+
]);
102+
}
103+
104+
test_class_method_valid() async {
105+
newFile('$testPackageLibPath/a.dart', r'''
106+
import augment 'test.dart';
107+
108+
class A {
109+
void foo() {}
110+
}
111+
''');
112+
113+
await assertNoErrorsInCode(r'''
114+
library augment 'a.dart';
115+
116+
augment class A {
117+
augment void foo() {}
118+
}
119+
''');
120+
}
121+
122+
test_class_setter() async {
123+
newFile('$testPackageLibPath/a.dart', r'''
124+
import augment 'test.dart';
125+
126+
class A {}
127+
''');
128+
129+
await assertErrorsInCode(r'''
130+
library augment 'a.dart';
131+
132+
augment class A {
133+
augment set foo(int _) {}
134+
}
135+
''', [
136+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 47, 7),
137+
]);
138+
}
139+
140+
test_mixin() async {
141+
newFile('$testPackageLibPath/a.dart', r'''
142+
import augment 'test.dart';
143+
''');
144+
145+
await assertErrorsInCode(r'''
146+
library augment 'a.dart';
147+
148+
augment mixin A {}
149+
''', [
150+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 27, 7),
151+
]);
152+
}
153+
154+
test_topLevel_function() async {
155+
newFile('$testPackageLibPath/a.dart', r'''
156+
import augment 'test.dart';
157+
''');
158+
159+
await assertErrorsInCode(r'''
160+
library augment 'a.dart';
161+
162+
augment void foo() {}
163+
''', [
164+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 27, 7),
165+
]);
166+
}
167+
168+
test_topLevel_function_valid() async {
169+
newFile('$testPackageLibPath/a.dart', r'''
170+
import augment 'test.dart';
171+
172+
void foo() {}
173+
''');
174+
175+
await assertNoErrorsInCode(r'''
176+
library augment 'a.dart';
177+
178+
augment void foo() {}
179+
''');
180+
}
181+
182+
test_topLevel_getter() async {
183+
newFile('$testPackageLibPath/a.dart', r'''
184+
import augment 'test.dart';
185+
''');
186+
187+
await assertErrorsInCode(r'''
188+
library augment 'a.dart';
189+
190+
augment int get foo => 0;
191+
''', [
192+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 27, 7),
193+
]);
194+
}
195+
196+
test_topLevel_setter() async {
197+
newFile('$testPackageLibPath/a.dart', r'''
198+
import augment 'test.dart';
199+
''');
200+
201+
await assertErrorsInCode(r'''
202+
library augment 'a.dart';
203+
204+
augment set foo(int _) {}
205+
''', [
206+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 27, 7),
207+
]);
208+
}
209+
210+
test_topLevel_variable() async {
211+
newFile('$testPackageLibPath/a.dart', r'''
212+
import augment 'test.dart';
213+
''');
214+
215+
await assertErrorsInCode(r'''
216+
library augment 'a.dart';
217+
218+
augment int foo = 0;
219+
''', [
220+
error(CompileTimeErrorCode.AUGMENTATION_WITHOUT_DECLARATION, 27, 7),
221+
]);
222+
}
223+
}

0 commit comments

Comments
 (0)