diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index f75600c8c2ef..b1cb8124235e 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -4385,6 +4385,15 @@ const MessageCode messageForInLoopWithConstVariable = const MessageCode( message: r"""A for-in loop-variable can't be 'const'.""", tip: r"""Try removing the 'const' modifier."""); +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeFunctionAsTypeParameter = messageFunctionAsTypeParameter; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageFunctionAsTypeParameter = const MessageCode( + "FunctionAsTypeParameter", + message: + r"""'Function' is a built-in identifier, could not used as a type identifier."""); + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Code codeFunctionTypeDefaultValue = messageFunctionTypeDefaultValue; @@ -4406,6 +4415,30 @@ const MessageCode messageFunctionTypedParameterVar = const MessageCode( r"""Function-typed parameters can't specify 'const', 'final' or 'var' in place of a return type.""", tip: r"""Try replacing the keyword with a return type."""); +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template< + Message Function(String name)> templateFunctionUsedAsDec = const Template< + Message Function(String name)>( + messageTemplate: + r"""'Function' is a built-in identifier, could not used as a #name name.""", + withArguments: _withArgumentsFunctionUsedAsDec); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeFunctionUsedAsDec = + const Code( + "FunctionUsedAsDec", +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsFunctionUsedAsDec(String name) { + if (name.isEmpty) throw 'No name provided'; + name = demangleMixinApplicationName(name); + return new Message(codeFunctionUsedAsDec, + message: + """'Function' is a built-in identifier, could not used as a ${name} name.""", + arguments: {'name': name}); +} + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Code codeGeneratorReturnsValue = messageGeneratorReturnsValue; diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart index aca996fcb196..a405e9aed448 100644 --- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart @@ -1464,6 +1464,48 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { new VoidTypeDeclarationBuilder(const VoidType(), this, charOffset)); } + void _checkBadFunctionParameter(List typeVariables) { + if (typeVariables == null || typeVariables.isEmpty) { + return; + } + + for (TypeVariableBuilder type in typeVariables) { + if (type.name == "Function") { + addProblem(messageFunctionAsTypeParameter, type.charOffset, + type.name.length, type.fileUri); + } + } + } + + void _checkBadFunctionDeclUse(String className, TypeParameterScopeKind kind, + int charOffset) { + String decType; + switch (kind) { + case TypeParameterScopeKind.classDeclaration: + decType = "class"; + break; + case TypeParameterScopeKind.mixinDeclaration: + decType = "mixin"; + break; + case TypeParameterScopeKind.extensionDeclaration: + decType = "extension"; + break; + default: + break; + } + if (className != "Function") { + return; + } + if (decType == "class" && importUri.scheme == "dart") { + // Allow declaration of class Function in the sdk. + return; + } + if (decType != null) { + addProblem(templateFunctionUsedAsDec.withArguments(decType), charOffset, + className?.length, fileUri); + } + } + /// Add a problem that might not be reported immediately. /// /// Problems will be issued after source information has been added. @@ -1573,6 +1615,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { int nameOffset, int endOffset, int supertypeOffset) { + _checkBadFunctionDeclUse(className, kind, nameOffset); + _checkBadFunctionParameter(typeVariables); // Nested declaration began in `OutlineBuilder.beginClassDeclaration`. TypeParameterScopeBuilder declaration = endNestedDeclaration(kind, className) @@ -1805,6 +1849,9 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { int startOffset, int nameOffset, int endOffset) { + _checkBadFunctionDeclUse( + extensionName, TypeParameterScopeKind.extensionDeclaration, nameOffset); + _checkBadFunctionParameter(typeVariables); // Nested declaration began in `OutlineBuilder.beginExtensionDeclaration`. TypeParameterScopeBuilder declaration = endNestedDeclaration( TypeParameterScopeKind.extensionDeclaration, extensionName) @@ -1836,7 +1883,6 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { nameOffset, endOffset, referenceFrom); - constructorReferences.clear(); Map typeVariablesByName = checkTypeVariables(typeVariables, extensionBuilder); diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index d15884ee54cc..23e753f74d1c 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -369,9 +369,11 @@ ForInLoopNotAssignable/part_wrapped_statement: Fail ForInLoopNotAssignable/statement: Fail ForInLoopTypeNotIterablePartNullability/example: Fail # Cannot occur but needed for symmetry with ForInLoopTypeNotIterableNullability ForInLoopWithConstVariable/example: Fail +FunctionAsTypeParameter/analyzerCode: Fail FunctionTypeDefaultValue/example: Fail FunctionTypedParameterVar/part_wrapped_script1: Fail FunctionTypedParameterVar/script1: Fail +FunctionUsedAsDec/analyzerCode: Fail GeneratorReturnsValue/example: Fail GetterNotFound/example: Fail GetterWithFormals/example: Fail diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index dafcd5fe7cc9..174bde3e4f31 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -1797,6 +1797,20 @@ NotAPrefixInTypeAnnotation: T.String field; } +FunctionUsedAsDec: + template: "'Function' is a built-in identifier, could not used as a #name name." + script: + - class Function {} + - extension Function on int {} + - mixin Function {} + +FunctionAsTypeParameter: + template: "'Function' is a built-in identifier, could not used as a type identifier." + script: + - class C {} + - mixin A {} + - extension A on List {} + UnresolvedPrefixInTypeAnnotation: template: "'#name.#name2' can't be used as a type because '#name' isn't defined." analyzerCode: NOT_A_TYPE diff --git a/pkg/front_end/testcases/general/function_bad_use.dart b/pkg/front_end/testcases/general/function_bad_use.dart new file mode 100644 index 000000000000..bc340517ae6f --- /dev/null +++ b/pkg/front_end/testcases/general/function_bad_use.dart @@ -0,0 +1,7 @@ +class Function {} + +class C {} + +mixin M implements List {} + +main() {} diff --git a/pkg/front_end/testcases/general/function_bad_use.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_bad_use.dart.textual_outline.expect new file mode 100644 index 000000000000..c115bf89fbea --- /dev/null +++ b/pkg/front_end/testcases/general/function_bad_use.dart.textual_outline.expect @@ -0,0 +1,6 @@ +class Function {} + +class C {} + +mixin M implements List {} +main() {} diff --git a/pkg/front_end/testcases/general/function_bad_use.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_bad_use.dart.textual_outline_modelled.expect new file mode 100644 index 000000000000..675fe74cafca --- /dev/null +++ b/pkg/front_end/testcases/general/function_bad_use.dart.textual_outline_modelled.expect @@ -0,0 +1,6 @@ +class C {} + +class Function {} + +main() {} +mixin M implements List {} diff --git a/pkg/front_end/testcases/general/function_bad_use.dart.weak.expect b/pkg/front_end/testcases/general/function_bad_use.dart.weak.expect new file mode 100644 index 000000000000..044f5c035de8 --- /dev/null +++ b/pkg/front_end/testcases/general/function_bad_use.dart.weak.expect @@ -0,0 +1,32 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/function_bad_use.dart:1:7: Error: 'Function' is a built-in identifier, could not used as a class name. +// class Function {} +// ^^^^^^^^ +// +// pkg/front_end/testcases/general/function_bad_use.dart:3:9: Error: 'Function' is a built-in identifier, could not used as a type identifier. +// class C {} +// ^^^^^^^^ +// +// pkg/front_end/testcases/general/function_bad_use.dart:5:9: Error: 'Function' is a built-in identifier, could not used as a type identifier. +// mixin M implements List {} +// ^^^^^^^^ +// +import self as self; +import "dart:core" as core; + +class Function extends core::Object { + synthetic constructor •() → self::Function + : super core::Object::•() + ; +} +class C extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +abstract class M extends core::Object implements core::List /*isMixinDeclaration*/ { +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/function_bad_use.dart.weak.outline.expect b/pkg/front_end/testcases/general/function_bad_use.dart.weak.outline.expect new file mode 100644 index 000000000000..9e4f7cff66fa --- /dev/null +++ b/pkg/front_end/testcases/general/function_bad_use.dart.weak.outline.expect @@ -0,0 +1,31 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/function_bad_use.dart:1:7: Error: 'Function' is a built-in identifier, could not used as a class name. +// class Function {} +// ^^^^^^^^ +// +// pkg/front_end/testcases/general/function_bad_use.dart:3:9: Error: 'Function' is a built-in identifier, could not used as a type identifier. +// class C {} +// ^^^^^^^^ +// +// pkg/front_end/testcases/general/function_bad_use.dart:5:9: Error: 'Function' is a built-in identifier, could not used as a type identifier. +// mixin M implements List {} +// ^^^^^^^^ +// +import self as self; +import "dart:core" as core; + +class Function extends core::Object { + synthetic constructor •() → self::Function + ; +} +class C extends core::Object { + synthetic constructor •() → self::C + ; +} +abstract class M extends core::Object implements core::List /*isMixinDeclaration*/ { +} +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/general/function_bad_use.dart.weak.transformed.expect b/pkg/front_end/testcases/general/function_bad_use.dart.weak.transformed.expect new file mode 100644 index 000000000000..044f5c035de8 --- /dev/null +++ b/pkg/front_end/testcases/general/function_bad_use.dart.weak.transformed.expect @@ -0,0 +1,32 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/function_bad_use.dart:1:7: Error: 'Function' is a built-in identifier, could not used as a class name. +// class Function {} +// ^^^^^^^^ +// +// pkg/front_end/testcases/general/function_bad_use.dart:3:9: Error: 'Function' is a built-in identifier, could not used as a type identifier. +// class C {} +// ^^^^^^^^ +// +// pkg/front_end/testcases/general/function_bad_use.dart:5:9: Error: 'Function' is a built-in identifier, could not used as a type identifier. +// mixin M implements List {} +// ^^^^^^^^ +// +import self as self; +import "dart:core" as core; + +class Function extends core::Object { + synthetic constructor •() → self::Function + : super core::Object::•() + ; +} +class C extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +abstract class M extends core::Object implements core::List /*isMixinDeclaration*/ { +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/ignore_function.dart b/pkg/front_end/testcases/general/ignore_function.dart index 347a8e2107ce..2e61179fc75d 100644 --- a/pkg/front_end/testcases/general/ignore_function.dart +++ b/pkg/front_end/testcases/general/ignore_function.dart @@ -14,8 +14,9 @@ class B implements Function { operator ==(other) => false; } +// CFE Error here: Function is built-in id, could not used as type id. class Function { core.bool operator ==(core.Object other) => false; } -main() {} +main() {} \ No newline at end of file diff --git a/pkg/front_end/testcases/general/ignore_function.dart.weak.expect b/pkg/front_end/testcases/general/ignore_function.dart.weak.expect index c25c94e4e65a..004e6cc768cf 100644 --- a/pkg/front_end/testcases/general/ignore_function.dart.weak.expect +++ b/pkg/front_end/testcases/general/ignore_function.dart.weak.expect @@ -1,4 +1,11 @@ library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/ignore_function.dart:18:7: Error: 'Function' is a built-in identifier, could not used as a class name. +// class Function { +// ^^^^^^^^ +// import self as self; import "dart:core" as core; diff --git a/pkg/front_end/testcases/general/ignore_function.dart.weak.outline.expect b/pkg/front_end/testcases/general/ignore_function.dart.weak.outline.expect index 0eda64b2fbb1..7b3df99f722f 100644 --- a/pkg/front_end/testcases/general/ignore_function.dart.weak.outline.expect +++ b/pkg/front_end/testcases/general/ignore_function.dart.weak.outline.expect @@ -1,4 +1,11 @@ library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/ignore_function.dart:18:7: Error: 'Function' is a built-in identifier, could not used as a class name. +// class Function { +// ^^^^^^^^ +// import self as self; import "dart:core" as core; diff --git a/pkg/front_end/testcases/general/ignore_function.dart.weak.transformed.expect b/pkg/front_end/testcases/general/ignore_function.dart.weak.transformed.expect index c25c94e4e65a..004e6cc768cf 100644 --- a/pkg/front_end/testcases/general/ignore_function.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/ignore_function.dart.weak.transformed.expect @@ -1,4 +1,11 @@ library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/ignore_function.dart:18:7: Error: 'Function' is a built-in identifier, could not used as a class name. +// class Function { +// ^^^^^^^^ +// import self as self; import "dart:core" as core;