Skip to content

Commit 103465c

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Report MAIN_HAS_MORE_THAN_TWO_REQUIRED_POSITIONAL_PARAMETERS and MAIN_HAS_REQUIRED_NAMED_PARAMETER.
Bug: dart-lang/sdk#43559 Change-Id: If74634187d411c0b008133b59c1c3e23e87319c3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166309 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
1 parent 4d77141 commit 103465c

File tree

7 files changed

+195
-1
lines changed

7 files changed

+195
-1
lines changed

pkg/analyzer/lib/error/error.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ const List<ErrorCode> errorCodeValues = [
260260
CompileTimeErrorCode.LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR,
261261
CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED,
262262
CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
263+
CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS,
264+
CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,
263265
CompileTimeErrorCode.MAIN_IS_NOT_FUNCTION,
264266
CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP,
265267
CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5460,6 +5460,22 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
54605460
"The element type '{0}' can't be assigned to the list type '{1}'.",
54615461
hasPublishedDocs: true);
54625462

5463+
static const CompileTimeErrorCode
5464+
MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS = CompileTimeErrorCode(
5465+
'MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS',
5466+
"The function 'main' can't have more than two required positional parameters.",
5467+
correction: "Try using a different name for the function, "
5468+
"or removing extra parameters.",
5469+
);
5470+
5471+
static const CompileTimeErrorCode MAIN_HAS_REQUIRED_NAMED_PARAMETERS =
5472+
CompileTimeErrorCode(
5473+
'MAIN_HAS_REQUIRED_NAMED_PARAMETERS',
5474+
"The function 'main' can't have any required named parameters.",
5475+
correction: "Try using a different name for the function, "
5476+
"or removing the 'required' modifier.",
5477+
);
5478+
54635479
static const CompileTimeErrorCode MAIN_IS_NOT_FUNCTION = CompileTimeErrorCode(
54645480
'MAIN_IS_NOT_FUNCTION',
54655481
"The declaration named 'main' must be a function.",

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,6 +3127,24 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
31273127
);
31283128
return;
31293129
}
3130+
3131+
var parameters = (element as FunctionElement).parameters;
3132+
var requiredPositional =
3133+
parameters.where((e) => e.isRequiredPositional).toList();
3134+
3135+
if (requiredPositional.length > 2) {
3136+
_errorReporter.reportErrorForNode(
3137+
CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,
3138+
nameNode,
3139+
);
3140+
}
3141+
3142+
if (parameters.any((e) => e.isRequiredNamed)) {
3143+
_errorReporter.reportErrorForNode(
3144+
CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS,
3145+
nameNode,
3146+
);
3147+
}
31303148
}
31313149

31323150
void _checkForMapTypeNotAssignable(SetOrMapLiteral literal) {

pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ main(int? a, int b) {
322322

323323
test_parameter_interfaceType_generic() async {
324324
await assertNoErrorsInCode('''
325-
main(List<int?>? a, List<int>? b, List<int?> c, List<int> d) {
325+
void f(List<int?>? a, List<int>? b, List<int?> c, List<int> d) {
326326
}
327327
''');
328328

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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/context_collection_resolution.dart';
9+
10+
main() {
11+
defineReflectiveSuite(() {
12+
defineReflectiveTests(MainHasRequiredNamedParametersTest);
13+
defineReflectiveTests(MainHasRequiredNamedParametersWithNullSafetyTest);
14+
});
15+
}
16+
17+
@reflectiveTest
18+
class MainHasRequiredNamedParametersTest extends PubPackageResolutionTest
19+
with MainHasRequiredNamedParametersTestCases {}
20+
21+
mixin MainHasRequiredNamedParametersTestCases on PubPackageResolutionTest {
22+
test_namedOptional() async {
23+
await resolveTestCode('''
24+
void main({int a = 0}) {}
25+
''');
26+
assertNoErrorsInResult();
27+
}
28+
}
29+
30+
@reflectiveTest
31+
class MainHasRequiredNamedParametersWithNullSafetyTest
32+
extends PubPackageResolutionTest
33+
with WithNullSafetyMixin, MainHasRequiredNamedParametersTestCases {
34+
test_namedRequired() async {
35+
await assertErrorsInCode('''
36+
void main({required List<String> a}) {}
37+
''', [
38+
error(CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS, 5, 4),
39+
]);
40+
}
41+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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/context_collection_resolution.dart';
9+
10+
main() {
11+
defineReflectiveSuite(() {
12+
defineReflectiveTests(MainHasTooManyRequiredPositionalParametersTest);
13+
defineReflectiveTests(
14+
MainHasTooManyRequiredPositionalParametersWithNullSafetyTest,
15+
);
16+
});
17+
}
18+
19+
@reflectiveTest
20+
class MainHasTooManyRequiredPositionalParametersTest
21+
extends PubPackageResolutionTest
22+
with MainHasTooManyRequiredPositionalParametersTestCases {}
23+
24+
mixin MainHasTooManyRequiredPositionalParametersTestCases
25+
on PubPackageResolutionTest {
26+
test_namedOptional_1() async {
27+
await resolveTestCode('''
28+
void main({int a = 0}) {}
29+
''');
30+
assertNoErrorsInResult();
31+
}
32+
33+
test_positionalOptional_1() async {
34+
await resolveTestCode('''
35+
void main([int a = 0]) {}
36+
''');
37+
assertNoErrorsInResult();
38+
}
39+
40+
test_positionalRequired_0() async {
41+
await resolveTestCode('''
42+
void main() {}
43+
''');
44+
assertNoErrorsInResult();
45+
}
46+
47+
test_positionalRequired_1() async {
48+
await resolveTestCode('''
49+
void main(args) {}
50+
''');
51+
assertNoErrorsInResult();
52+
}
53+
54+
test_positionalRequired_2() async {
55+
await resolveTestCode('''
56+
void main(args, int a) {}
57+
''');
58+
assertNoErrorsInResult();
59+
}
60+
61+
test_positionalRequired_2_positionalOptional_1() async {
62+
await resolveTestCode('''
63+
void main(args, int a, [int b = 0]) {}
64+
''');
65+
assertNoErrorsInResult();
66+
}
67+
68+
test_positionalRequired_3() async {
69+
await resolveTestCode('''
70+
void main(args, int a, int b) {}
71+
''');
72+
assertErrorsInResult(expectedErrorsByNullability(nullable: [
73+
error(
74+
CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,
75+
5,
76+
4),
77+
], legacy: []));
78+
}
79+
80+
test_positionalRequired_3_namedOptional_1() async {
81+
await resolveTestCode('''
82+
void main(args, int a, int b, {int c = 0}) {}
83+
''');
84+
assertErrorsInResult(expectedErrorsByNullability(nullable: [
85+
error(
86+
CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,
87+
5,
88+
4),
89+
], legacy: []));
90+
}
91+
}
92+
93+
@reflectiveTest
94+
class MainHasTooManyRequiredPositionalParametersWithNullSafetyTest
95+
extends PubPackageResolutionTest
96+
with
97+
WithNullSafetyMixin,
98+
MainHasTooManyRequiredPositionalParametersTestCases {
99+
test_positionalRequired_3_namedRequired_1() async {
100+
await resolveTestCode('''
101+
void main(args, int a, int b, {required int c}) {}
102+
''');
103+
assertErrorsInResult(expectedErrorsByNullability(nullable: [
104+
error(CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS, 5, 4),
105+
error(
106+
CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,
107+
5,
108+
4),
109+
], legacy: []));
110+
}
111+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,10 @@ import 'late_final_local_already_assigned_test.dart'
344344
as late_final_local_already_assigned;
345345
import 'list_element_type_not_assignable_test.dart'
346346
as list_element_type_not_assignable;
347+
import 'main_has_required_named_parameters_test.dart'
348+
as main_has_required_named_parameters;
349+
import 'main_has_too_many_required_positional_parameters_test.dart'
350+
as main_has_too_many_required_positional_parameters;
347351
import 'main_is_not_function_test.dart' as main_is_not_function;
348352
import 'map_entry_not_in_map_test.dart' as map_entry_not_in_map;
349353
import 'map_key_type_not_assignable_test.dart' as map_key_type_not_assignable;
@@ -873,6 +877,8 @@ main() {
873877
late_final_field_with_const_constructor.main();
874878
late_final_local_already_assigned.main();
875879
list_element_type_not_assignable.main();
880+
main_has_required_named_parameters.main();
881+
main_has_too_many_required_positional_parameters.main();
876882
main_is_not_function.main();
877883
map_entry_not_in_map.main();
878884
map_key_type_not_assignable.main();

0 commit comments

Comments
 (0)