diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart index 0134b77d0d35..ee91c887e300 100644 --- a/pkg/analyzer/lib/error/error.dart +++ b/pkg/analyzer/lib/error/error.dart @@ -497,7 +497,6 @@ const List errorCodeValues = [ HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, HintCode.DEPRECATED_EXTENDS_FUNCTION, - HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, HintCode.DEPRECATED_MEMBER_USE, HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE, diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart index 9900a5e19a43..efe0821dab2f 100644 --- a/pkg/analyzer/lib/src/error/codes.dart +++ b/pkg/analyzer/lib/src/error/codes.dart @@ -13720,7 +13720,6 @@ class CompileTimeErrorCode extends AnalyzerErrorCode { "The type '{0}' implied by the 'yield' expression must be assignable " "to '{1}'.", hasPublishedDocs: true); - /** * Initialize a newly created error code to have the given [name]. The message * associated with the error will be created from the given [message] diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart index 0d097e9a9ce3..e43ffa2c89b5 100644 --- a/pkg/analyzer/lib/src/generated/error_verifier.dart +++ b/pkg/analyzer/lib/src/generated/error_verifier.dart @@ -609,6 +609,7 @@ class ErrorVerifier extends RecursiveAstVisitor _checkForBuiltInIdentifierAsName( name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME); } + _checkExtensionBadFunctionUse(node); super.visitExtensionDeclaration(node); _enclosingExtension = null; } @@ -959,6 +960,7 @@ class ErrorVerifier extends RecursiveAstVisitor _checkForMainFunction(node.name); _checkForWrongTypeParameterVarianceInSuperinterfaces(); // _checkForBadFunctionUse(node); + _checkMixinBasFunctionUse(node); super.visitMixinDeclaration(node); } finally { _enclosingClass = outerClass; @@ -1575,20 +1577,89 @@ class ErrorVerifier extends RecursiveAstVisitor } } + /// Verifies that the mixin is not named `Function` and that its type + /// parameters don't named `Function`. + void _checkMixinBasFunctionUse(MixinDeclaration node) { + final functionToken = "Function"; + var typeParams = node.typeParameters; + var onClause = node.onClause; + if (node.name.name == functionToken) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, node.name, + [functionToken]); + } + if (typeParams != null) { + for (TypeParameter parameter in typeParams.typeParameters) { + if (parameter.name.name == functionToken) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME, + parameter, [functionToken]); + } + } + } + // Check Mixin OnClause + if (onClause != null) { + for (TypeName type in onClause.superclassConstraints) { + var mixinElement = type.name.staticElement; + if (mixinElement != null && mixinElement.name == functionToken) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, type, + [type.name], + ); + } + } + } + } + + /// Verifies that the extension is not named `Function` and that its type + /// parameters don't named `Function`. + void _checkExtensionBadFunctionUse(ExtensionDeclaration node) { + final functionToken = "Function"; + var typeParams = node.typeParameters; + if (node.name != null && node.name?.name == functionToken) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME, node.name + !, [functionToken]); + } + if (typeParams != null) { + for (TypeParameter parameter in typeParams.typeParameters) { + if (parameter.name.name == functionToken) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME, + parameter, [functionToken]); + } + } + } + } + /// Verifies that the class is not named `Function` and that it doesn't /// extends/implements/mixes in `Function`. + /// Also Verifies that the class's type parameters is not named `Function`. void _checkForBadFunctionUse(ClassDeclaration node) { var extendsClause = node.extendsClause; var withClause = node.withClause; + var typeParams = node.typeParameters; + final functionToken = "Function"; - if (node.name.name == "Function") { + if (node.name.name == functionToken) { errorReporter.reportErrorForNode( - HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, node.name); + CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, node.name, + [functionToken]); + } + + if (typeParams != null) { + for (TypeParameter parameter in typeParams.typeParameters) { + if (parameter.name.name == functionToken) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME, + parameter, [functionToken]); + } + } } if (extendsClause != null) { var superElement = extendsClause.superclass.name.staticElement; - if (superElement != null && superElement.name == "Function") { + if (superElement != null && superElement.name == functionToken) { errorReporter.reportErrorForNode( HintCode.DEPRECATED_EXTENDS_FUNCTION, extendsClause.superclass); } @@ -1597,7 +1668,7 @@ class ErrorVerifier extends RecursiveAstVisitor if (withClause != null) { for (TypeName type in withClause.mixinTypes) { var mixinElement = type.name.staticElement; - if (mixinElement != null && mixinElement.name == "Function") { + if (mixinElement != null && mixinElement.name == functionToken) { errorReporter.reportErrorForNode( HintCode.DEPRECATED_MIXIN_FUNCTION, type); } diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_extends_function_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_extends_function_test.dart index 2e97f2543a6b..3fdcffe64f87 100644 --- a/pkg/analyzer/test/src/diagnostics/deprecated_extends_function_test.dart +++ b/pkg/analyzer/test/src/diagnostics/deprecated_extends_function_test.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/dart/error/hint_codes.dart'; +import 'package:analyzer/src/error/codes.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/context_collection_resolution.dart'; @@ -28,7 +29,7 @@ class A extends Function {} class Function {} class A extends Function {} ''', [ - error(HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, 6, 8), + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 6, 8), error(HintCode.DEPRECATED_EXTENDS_FUNCTION, 34, 8), ]); } diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_function_as_type_identifier_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_function_as_type_identifier_test.dart new file mode 100644 index 000000000000..1b2b18de2271 --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/deprecated_function_as_type_identifier_test.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/dart/error/syntactic_errors.dart'; +import 'package:analyzer/src/error/codes.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/context_collection_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(DeprecatedFunctionAsTypeIdentifierTest); + }); +} + +@reflectiveTest +class DeprecatedFunctionAsTypeIdentifierTest extends PubPackageResolutionTest { + test_typedef() async { + await assertErrorsInCode(''' +typedef Function = int; +typedef F = int; +''', [ + error(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 8, 8), + ]); + } + + test_extension() async { + await assertErrorsInCode(''' +extension Function on List {} +extension E on List {} +''', [ + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME, 10, 8), + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME, 42, 8), + ]); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_function_class_declaration_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_function_class_declaration_test.dart index 6221d24ec8e4..52b0bff7d584 100644 --- a/pkg/analyzer/test/src/diagnostics/deprecated_function_class_declaration_test.dart +++ b/pkg/analyzer/test/src/diagnostics/deprecated_function_class_declaration_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/src/dart/error/hint_codes.dart'; +import 'package:analyzer/src/error/codes.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/context_collection_resolution.dart'; @@ -19,7 +19,17 @@ class DeprecatedFunctionClassDeclarationTest extends PubPackageResolutionTest { await assertErrorsInCode(''' class Function {} ''', [ - error(HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, 6, 8), + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 6, 8), + ]); + } + + test_typeparameter() async { + await assertErrorsInCode(''' +class Function {} +class C {} +''', [ + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 6, 8), + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME, 26, 8), ]); } } diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_mixin_function_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_mixin_function_test.dart index e6fd57e10cd0..eb27f2586891 100644 --- a/pkg/analyzer/test/src/diagnostics/deprecated_mixin_function_test.dart +++ b/pkg/analyzer/test/src/diagnostics/deprecated_mixin_function_test.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/dart/error/hint_codes.dart'; +import 'package:analyzer/src/error/codes.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/context_collection_resolution.dart'; @@ -28,8 +29,26 @@ class A extends Object with Function {} class Function {} class A extends Object with Function {} ''', [ - error(HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, 6, 8), + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 6, 8), error(HintCode.DEPRECATED_MIXIN_FUNCTION, 46, 8), ]); } + + test_mixin() async { + await assertErrorsInCode(''' +mixin Function {} +mixin M implements List {} +''', [ + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 6, 8), + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME, 26, 8), + ]); + } + + test_mixin_onclause() async { + await assertErrorsInCode(''' +mixin A on Function {} +''', [ + error(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 11, 8), + ]); + } } diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart index 3d1234d84d1c..ea6b88c1ce86 100644 --- a/pkg/analyzer/test/src/diagnostics/test_all.dart +++ b/pkg/analyzer/test/src/diagnostics/test_all.dart @@ -121,6 +121,8 @@ import 'deferred_import_of_extension_test.dart' as deferred_import_of_extension; import 'definitely_unassigned_late_local_variable_test.dart' as definitely_unassigned_late_local_variable; import 'deprecated_extends_function_test.dart' as deprecated_extends_function; +import 'deprecated_function_as_type_identifier_test.dart' + as deprecated_function_as_type_identifier; import 'deprecated_function_class_declaration_test.dart' as deprecated_function_class_declaration; import 'deprecated_member_use_test.dart' as deprecated_member_use; @@ -766,6 +768,7 @@ main() { deferred_import_of_extension.main(); definitely_unassigned_late_local_variable.main(); deprecated_extends_function.main(); + deprecated_function_as_type_identifier.main(); deprecated_function_class_declaration.main(); deprecated_member_use.main(); deprecated_mixin_function.main();