Skip to content

Commit 28e6468

Browse files
committed
Cause CompileTimeError in analyzer when use 'Function' as a type:
1. cause CompileTimeErrorCode.FUNCTION_CLASS_DECLARATION when declare class named 'Function'. 2. cause CompileTimeErrorCode.FUNCTION_MIXIN_DECLARATION when declare mixin named 'Function'. 3. cause CompileTimeErrorCode.FUNCTION_EXTENSION_DECLARATION when declare extension named 'Function'. 4. cause CompileTimeErrorCode.FUNCTION_AS_TYPE_PARAMETER when type parameters contain parma named 'Function'.
1 parent b802aad commit 28e6468

8 files changed

+154
-9
lines changed

pkg/analyzer/lib/error/error.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,10 @@ const List<ErrorCode> errorCodeValues = [
461461
CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR,
462462
CompileTimeErrorCode.YIELD_IN_NON_GENERATOR,
463463
CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
464+
CompileTimeErrorCode.FUNCTION_CLASS_DECLARATION,
465+
CompileTimeErrorCode.FUNCTION_AS_TYPE_PARAMETER,
466+
CompileTimeErrorCode.FUNCTION_EXTENSION_DECLARATION,
467+
CompileTimeErrorCode.FUNCTION_MIXIN_DECLARATION,
464468
FfiCode.ANNOTATION_ON_POINTER_FIELD,
465469
FfiCode.EMPTY_STRUCT,
466470
FfiCode.EXTRA_ANNOTATION_ON_STRUCT_FIELD,
@@ -497,7 +501,6 @@ const List<ErrorCode> errorCodeValues = [
497501
HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
498502
HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
499503
HintCode.DEPRECATED_EXTENDS_FUNCTION,
500-
HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION,
501504
HintCode.DEPRECATED_MEMBER_USE,
502505
HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE,
503506
HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE,

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13721,6 +13721,34 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
1372113721
"to '{1}'.",
1372213722
hasPublishedDocs: true);
1372313723

13724+
static const CompileTimeErrorCode FUNCTION_CLASS_DECLARATION =
13725+
CompileTimeErrorCode(
13726+
"FUNCTION_CLASS_DECLARATION",
13727+
"'Function' is a built-in identifier, could not used as a class name",
13728+
correction: "Try renaming the class.",
13729+
);
13730+
13731+
static const CompileTimeErrorCode FUNCTION_AS_TYPE_PARAMETER =
13732+
CompileTimeErrorCode(
13733+
"FUNCTION_AS_TYPE_PARAMETER",
13734+
"'Function' is a built-in identifier, could not used as a type parameter name",
13735+
correction: "Try renaming the type parameter.",
13736+
);
13737+
13738+
static const CompileTimeErrorCode FUNCTION_EXTENSION_DECLARATION =
13739+
CompileTimeErrorCode(
13740+
"FUNCTION_EXTENSION_DECLARATION",
13741+
"'Function' is a built-in identifier, could not used as a extension name",
13742+
correction: "Try renaming the extension.",
13743+
);
13744+
13745+
static const CompileTimeErrorCode FUNCTION_MIXIN_DECLARATION =
13746+
CompileTimeErrorCode(
13747+
"FUNCTION_MIXIN_DECLARATION",
13748+
"'Function' is a built-in identifier, could not used as a mixin name",
13749+
correction: "Try renaming the mixin.",
13750+
);
13751+
1372413752
/**
1372513753
* Initialize a newly created error code to have the given [name]. The message
1372613754
* associated with the error will be created from the given [message]

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

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
609609
_checkForBuiltInIdentifierAsName(
610610
name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME);
611611
}
612+
_checkExtensionBadFunctionUse(node);
612613
super.visitExtensionDeclaration(node);
613614
_enclosingExtension = null;
614615
}
@@ -959,6 +960,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
959960
_checkForMainFunction(node.name);
960961
_checkForWrongTypeParameterVarianceInSuperinterfaces();
961962
// _checkForBadFunctionUse(node);
963+
_checkMixinBasFunctionUse(node);
962964
super.visitMixinDeclaration(node);
963965
} finally {
964966
_enclosingClass = outerClass;
@@ -1575,20 +1577,70 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
15751577
}
15761578
}
15771579

1580+
/// Verifies that the mixin is not named `Function` and that its type
1581+
/// parameters don't named `Function`.
1582+
void _checkMixinBasFunctionUse(MixinDeclaration node) {
1583+
final functionToken = "Function";
1584+
var typeParams = node.typeParameters;
1585+
if (node.name.name == functionToken) {
1586+
errorReporter.reportErrorForNode(
1587+
CompileTimeErrorCode.FUNCTION_MIXIN_DECLARATION, node.name);
1588+
}
1589+
if (typeParams != null) {
1590+
for (TypeParameter parameter in typeParams.typeParameters) {
1591+
if (parameter.name.name == functionToken) {
1592+
errorReporter.reportErrorForNode(
1593+
CompileTimeErrorCode.FUNCTION_AS_TYPE_PARAMETER, parameter);
1594+
}
1595+
}
1596+
}
1597+
}
1598+
1599+
/// Verifies that the extension is not named `Function` and that its type
1600+
/// parameters don't named `Function`.
1601+
void _checkExtensionBadFunctionUse(ExtensionDeclaration node) {
1602+
final functionToken = "Function";
1603+
var typeParams = node.typeParameters;
1604+
if (node.name != null && node.name?.name == functionToken) {
1605+
errorReporter.reportErrorForNode(
1606+
CompileTimeErrorCode.FUNCTION_EXTENSION_DECLARATION, node.name!);
1607+
}
1608+
if (typeParams != null) {
1609+
for (TypeParameter parameter in typeParams.typeParameters) {
1610+
if (parameter.name.name == functionToken) {
1611+
errorReporter.reportErrorForNode(
1612+
CompileTimeErrorCode.FUNCTION_AS_TYPE_PARAMETER, parameter);
1613+
}
1614+
}
1615+
}
1616+
}
1617+
15781618
/// Verifies that the class is not named `Function` and that it doesn't
15791619
/// extends/implements/mixes in `Function`.
1620+
/// Also Verifies that the class's type parameters is not named `Function`.
15801621
void _checkForBadFunctionUse(ClassDeclaration node) {
15811622
var extendsClause = node.extendsClause;
15821623
var withClause = node.withClause;
1624+
var typeParams = node.typeParameters;
1625+
final functionToken = "Function";
15831626

1584-
if (node.name.name == "Function") {
1627+
if (node.name.name == functionToken) {
15851628
errorReporter.reportErrorForNode(
1586-
HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, node.name);
1629+
CompileTimeErrorCode.FUNCTION_CLASS_DECLARATION, node.name);
1630+
}
1631+
1632+
if (typeParams != null) {
1633+
for (TypeParameter parameter in typeParams.typeParameters) {
1634+
if (parameter.name.name == functionToken) {
1635+
errorReporter.reportErrorForNode(
1636+
CompileTimeErrorCode.FUNCTION_AS_TYPE_PARAMETER, parameter);
1637+
}
1638+
}
15871639
}
15881640

15891641
if (extendsClause != null) {
15901642
var superElement = extendsClause.superclass.name.staticElement;
1591-
if (superElement != null && superElement.name == "Function") {
1643+
if (superElement != null && superElement.name == functionToken) {
15921644
errorReporter.reportErrorForNode(
15931645
HintCode.DEPRECATED_EXTENDS_FUNCTION, extendsClause.superclass);
15941646
}
@@ -1597,7 +1649,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
15971649
if (withClause != null) {
15981650
for (TypeName type in withClause.mixinTypes) {
15991651
var mixinElement = type.name.staticElement;
1600-
if (mixinElement != null && mixinElement.name == "Function") {
1652+
if (mixinElement != null && mixinElement.name == functionToken) {
16011653
errorReporter.reportErrorForNode(
16021654
HintCode.DEPRECATED_MIXIN_FUNCTION, type);
16031655
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analyzer/src/dart/error/hint_codes.dart';
6+
import 'package:analyzer/src/error/codes.dart';
67
import 'package:test_reflective_loader/test_reflective_loader.dart';
78

89
import '../dart/resolution/context_collection_resolution.dart';
@@ -28,7 +29,7 @@ class A extends Function {}
2829
class Function {}
2930
class A extends Function {}
3031
''', [
31-
error(HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, 6, 8),
32+
error(CompileTimeErrorCode.FUNCTION_CLASS_DECLARATION, 6, 8),
3233
error(HintCode.DEPRECATED_EXTENDS_FUNCTION, 34, 8),
3334
]);
3435
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2021, 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/dart/error/syntactic_errors.dart';
6+
import 'package:analyzer/src/error/codes.dart';
7+
import 'package:test_reflective_loader/test_reflective_loader.dart';
8+
9+
import '../dart/resolution/context_collection_resolution.dart';
10+
11+
main() {
12+
defineReflectiveSuite(() {
13+
defineReflectiveTests(DeprecatedFunctionAsTypeIdentifierTest);
14+
});
15+
}
16+
17+
@reflectiveTest
18+
class DeprecatedFunctionAsTypeIdentifierTest extends PubPackageResolutionTest {
19+
test_typedef() async {
20+
await assertErrorsInCode('''
21+
typedef Function = int;
22+
typedef F<Function> = int;
23+
''', [
24+
error(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 8, 8),
25+
]);
26+
}
27+
28+
test_extension() async {
29+
await assertErrorsInCode('''
30+
extension Function on List {}
31+
extension E<Function> on List<Function> {}
32+
''', [
33+
error(CompileTimeErrorCode.FUNCTION_EXTENSION_DECLARATION, 10, 8),
34+
error(CompileTimeErrorCode.FUNCTION_AS_TYPE_PARAMETER, 42, 8),
35+
]);
36+
}
37+
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'package:analyzer/src/dart/error/hint_codes.dart';
5+
import 'package:analyzer/src/error/codes.dart';
66
import 'package:test_reflective_loader/test_reflective_loader.dart';
77

88
import '../dart/resolution/context_collection_resolution.dart';
@@ -19,7 +19,17 @@ class DeprecatedFunctionClassDeclarationTest extends PubPackageResolutionTest {
1919
await assertErrorsInCode('''
2020
class Function {}
2121
''', [
22-
error(HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, 6, 8),
22+
error(CompileTimeErrorCode.FUNCTION_CLASS_DECLARATION, 6, 8),
23+
]);
24+
}
25+
26+
test_typeparameter() async {
27+
await assertErrorsInCode('''
28+
class Function {}
29+
class C<Function> {}
30+
''', [
31+
error(CompileTimeErrorCode.FUNCTION_CLASS_DECLARATION, 6, 8),
32+
error(CompileTimeErrorCode.FUNCTION_AS_TYPE_PARAMETER, 26, 8),
2333
]);
2434
}
2535
}

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analyzer/src/dart/error/hint_codes.dart';
6+
import 'package:analyzer/src/error/codes.dart';
67
import 'package:test_reflective_loader/test_reflective_loader.dart';
78

89
import '../dart/resolution/context_collection_resolution.dart';
@@ -28,8 +29,18 @@ class A extends Object with Function {}
2829
class Function {}
2930
class A extends Object with Function {}
3031
''', [
31-
error(HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, 6, 8),
32+
error(CompileTimeErrorCode.FUNCTION_CLASS_DECLARATION, 6, 8),
3233
error(HintCode.DEPRECATED_MIXIN_FUNCTION, 46, 8),
3334
]);
3435
}
36+
37+
test_mixin() async {
38+
await assertErrorsInCode('''
39+
mixin Function {}
40+
mixin M<Function> implements List<Function> {}
41+
''', [
42+
error(CompileTimeErrorCode.FUNCTION_MIXIN_DECLARATION, 6, 8),
43+
error(CompileTimeErrorCode.FUNCTION_AS_TYPE_PARAMETER, 26, 8),
44+
]);
45+
}
3546
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ import 'definitely_unassigned_late_local_variable_test.dart'
123123
import 'deprecated_extends_function_test.dart' as deprecated_extends_function;
124124
import 'deprecated_function_class_declaration_test.dart'
125125
as deprecated_function_class_declaration;
126+
import 'deprecated_function_as_type_identifier_test.dart'
127+
as deprecated_function_as_type_identifier;
126128
import 'deprecated_member_use_test.dart' as deprecated_member_use;
127129
import 'deprecated_mixin_function_test.dart' as deprecated_mixin_function;
128130
import 'division_optimization_test.dart' as division_optimization;
@@ -767,6 +769,7 @@ main() {
767769
definitely_unassigned_late_local_variable.main();
768770
deprecated_extends_function.main();
769771
deprecated_function_class_declaration.main();
772+
deprecated_function_as_type_identifier.main();
770773
deprecated_member_use.main();
771774
deprecated_mixin_function.main();
772775
division_optimization.main();

0 commit comments

Comments
 (0)