Skip to content

Commit 5787ad0

Browse files
lfkdskcommit-bot@chromium.org
authored andcommitted
[CFE] add 'Function' as type identifier check in CFE
try resolve #45705 @eernstg Closes #45736 #45736 GitOrigin-RevId: 2d91c32 Change-Id: Ic416287137495926efe1d03da7d484202bd11272 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195761 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 82ea841 commit 5787ad0

14 files changed

+233
-2
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

+33
Original file line numberDiff line numberDiff line change
@@ -4385,6 +4385,15 @@ const MessageCode messageForInLoopWithConstVariable = const MessageCode(
43854385
message: r"""A for-in loop-variable can't be 'const'.""",
43864386
tip: r"""Try removing the 'const' modifier.""");
43874387

4388+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4389+
const Code<Null> codeFunctionAsTypeParameter = messageFunctionAsTypeParameter;
4390+
4391+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4392+
const MessageCode messageFunctionAsTypeParameter = const MessageCode(
4393+
"FunctionAsTypeParameter",
4394+
message:
4395+
r"""'Function' is a built-in identifier, could not used as a type identifier.""");
4396+
43884397
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
43894398
const Code<Null> codeFunctionTypeDefaultValue = messageFunctionTypeDefaultValue;
43904399

@@ -4406,6 +4415,30 @@ const MessageCode messageFunctionTypedParameterVar = const MessageCode(
44064415
r"""Function-typed parameters can't specify 'const', 'final' or 'var' in place of a return type.""",
44074416
tip: r"""Try replacing the keyword with a return type.""");
44084417

4418+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4419+
const Template<
4420+
Message Function(String name)> templateFunctionUsedAsDec = const Template<
4421+
Message Function(String name)>(
4422+
messageTemplate:
4423+
r"""'Function' is a built-in identifier, could not used as a #name name.""",
4424+
withArguments: _withArgumentsFunctionUsedAsDec);
4425+
4426+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4427+
const Code<Message Function(String name)> codeFunctionUsedAsDec =
4428+
const Code<Message Function(String name)>(
4429+
"FunctionUsedAsDec",
4430+
);
4431+
4432+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4433+
Message _withArgumentsFunctionUsedAsDec(String name) {
4434+
if (name.isEmpty) throw 'No name provided';
4435+
name = demangleMixinApplicationName(name);
4436+
return new Message(codeFunctionUsedAsDec,
4437+
message:
4438+
"""'Function' is a built-in identifier, could not used as a ${name} name.""",
4439+
arguments: {'name': name});
4440+
}
4441+
44094442
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
44104443
const Code<Null> codeGeneratorReturnsValue = messageGeneratorReturnsValue;
44114444

pkg/front_end/lib/src/fasta/source/source_library_builder.dart

+47-1
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,48 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
14651465
new VoidTypeDeclarationBuilder(const VoidType(), this, charOffset));
14661466
}
14671467

1468+
void _checkBadFunctionParameter(List<TypeVariableBuilder> typeVariables) {
1469+
if (typeVariables == null || typeVariables.isEmpty) {
1470+
return;
1471+
}
1472+
1473+
for (TypeVariableBuilder type in typeVariables) {
1474+
if (type.name == "Function") {
1475+
addProblem(messageFunctionAsTypeParameter, type.charOffset,
1476+
type.name.length, type.fileUri);
1477+
}
1478+
}
1479+
}
1480+
1481+
void _checkBadFunctionDeclUse(String className, TypeParameterScopeKind kind,
1482+
int charOffset) {
1483+
String decType;
1484+
switch (kind) {
1485+
case TypeParameterScopeKind.classDeclaration:
1486+
decType = "class";
1487+
break;
1488+
case TypeParameterScopeKind.mixinDeclaration:
1489+
decType = "mixin";
1490+
break;
1491+
case TypeParameterScopeKind.extensionDeclaration:
1492+
decType = "extension";
1493+
break;
1494+
default:
1495+
break;
1496+
}
1497+
if (className != "Function") {
1498+
return;
1499+
}
1500+
if (decType == "class" && importUri.scheme == "dart") {
1501+
// Allow declaration of class Function in the sdk.
1502+
return;
1503+
}
1504+
if (decType != null) {
1505+
addProblem(templateFunctionUsedAsDec.withArguments(decType), charOffset,
1506+
className?.length, fileUri);
1507+
}
1508+
}
1509+
14681510
/// Add a problem that might not be reported immediately.
14691511
///
14701512
/// Problems will be issued after source information has been added.
@@ -1574,6 +1616,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
15741616
int nameOffset,
15751617
int endOffset,
15761618
int supertypeOffset) {
1619+
_checkBadFunctionDeclUse(className, kind, nameOffset);
1620+
_checkBadFunctionParameter(typeVariables);
15771621
// Nested declaration began in `OutlineBuilder.beginClassDeclaration`.
15781622
TypeParameterScopeBuilder declaration =
15791623
endNestedDeclaration(kind, className)
@@ -1806,6 +1850,9 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
18061850
int startOffset,
18071851
int nameOffset,
18081852
int endOffset) {
1853+
_checkBadFunctionDeclUse(
1854+
extensionName, TypeParameterScopeKind.extensionDeclaration, nameOffset);
1855+
_checkBadFunctionParameter(typeVariables);
18091856
// Nested declaration began in `OutlineBuilder.beginExtensionDeclaration`.
18101857
TypeParameterScopeBuilder declaration = endNestedDeclaration(
18111858
TypeParameterScopeKind.extensionDeclaration, extensionName)
@@ -1837,7 +1884,6 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
18371884
nameOffset,
18381885
endOffset,
18391886
referenceFrom);
1840-
18411887
constructorReferences.clear();
18421888
Map<String, TypeVariableBuilder> typeVariablesByName =
18431889
checkTypeVariables(typeVariables, extensionBuilder);

pkg/front_end/messages.status

+2
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,11 @@ ForInLoopNotAssignable/part_wrapped_statement: Fail
369369
ForInLoopNotAssignable/statement: Fail
370370
ForInLoopTypeNotIterablePartNullability/example: Fail # Cannot occur but needed for symmetry with ForInLoopTypeNotIterableNullability
371371
ForInLoopWithConstVariable/example: Fail
372+
FunctionAsTypeParameter/analyzerCode: Fail
372373
FunctionTypeDefaultValue/example: Fail
373374
FunctionTypedParameterVar/part_wrapped_script1: Fail
374375
FunctionTypedParameterVar/script1: Fail
376+
FunctionUsedAsDec/analyzerCode: Fail
375377
GeneratorReturnsValue/example: Fail
376378
GetterNotFound/example: Fail
377379
GetterWithFormals/example: Fail

pkg/front_end/messages.yaml

+14
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,20 @@ NotAPrefixInTypeAnnotation:
17971797
T.String field;
17981798
}
17991799
1800+
FunctionUsedAsDec:
1801+
template: "'Function' is a built-in identifier, could not used as a #name name."
1802+
script:
1803+
- class Function {}
1804+
- extension Function on int {}
1805+
- mixin Function {}
1806+
1807+
FunctionAsTypeParameter:
1808+
template: "'Function' is a built-in identifier, could not used as a type identifier."
1809+
script:
1810+
- class C<Function> {}
1811+
- mixin A<Function> {}
1812+
- extension A<Function> on List<Function> {}
1813+
18001814
UnresolvedPrefixInTypeAnnotation:
18011815
template: "'#name.#name2' can't be used as a type because '#name' isn't defined."
18021816
analyzerCode: NOT_A_TYPE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Function {}
2+
3+
class C<Function> {}
4+
5+
mixin M<Function> implements List<Function> {}
6+
7+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Function {}
2+
3+
class C<Function> {}
4+
5+
mixin M<Function> implements List<Function> {}
6+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class C<Function> {}
2+
3+
class Function {}
4+
5+
main() {}
6+
mixin M<Function> implements List<Function> {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// 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.
6+
// class Function {}
7+
// ^^^^^^^^
8+
//
9+
// 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.
10+
// class C<Function> {}
11+
// ^^^^^^^^
12+
//
13+
// 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.
14+
// mixin M<Function> implements List<Function> {}
15+
// ^^^^^^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
class Function extends core::Object {
21+
synthetic constructor •() → self::Function
22+
: super core::Object::•()
23+
;
24+
}
25+
class C<Function extends core::Object? = dynamic> extends core::Object {
26+
synthetic constructor •() → self::C<self::C::Function%>
27+
: super core::Object::•()
28+
;
29+
}
30+
abstract class M<Function extends core::Object? = dynamic> extends core::Object implements core::List<self::M::Function%> /*isMixinDeclaration*/ {
31+
}
32+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// 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.
6+
// class Function {}
7+
// ^^^^^^^^
8+
//
9+
// 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.
10+
// class C<Function> {}
11+
// ^^^^^^^^
12+
//
13+
// 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.
14+
// mixin M<Function> implements List<Function> {}
15+
// ^^^^^^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
class Function extends core::Object {
21+
synthetic constructor •() → self::Function
22+
;
23+
}
24+
class C<Function extends core::Object? = dynamic> extends core::Object {
25+
synthetic constructor •() → self::C<self::C::Function%>
26+
;
27+
}
28+
abstract class M<Function extends core::Object? = dynamic> extends core::Object implements core::List<self::M::Function%> /*isMixinDeclaration*/ {
29+
}
30+
static method main() → dynamic
31+
;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// 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.
6+
// class Function {}
7+
// ^^^^^^^^
8+
//
9+
// 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.
10+
// class C<Function> {}
11+
// ^^^^^^^^
12+
//
13+
// 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.
14+
// mixin M<Function> implements List<Function> {}
15+
// ^^^^^^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
class Function extends core::Object {
21+
synthetic constructor •() → self::Function
22+
: super core::Object::•()
23+
;
24+
}
25+
class C<Function extends core::Object? = dynamic> extends core::Object {
26+
synthetic constructor •() → self::C<self::C::Function%>
27+
: super core::Object::•()
28+
;
29+
}
30+
abstract class M<Function extends core::Object? = dynamic> extends core::Object implements core::List<self::M::Function%> /*isMixinDeclaration*/ {
31+
}
32+
static method main() → dynamic {}

pkg/front_end/testcases/general/ignore_function.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ class B implements Function {
1414
operator ==(other) => false;
1515
}
1616

17+
// CFE Error here: Function is built-in id, could not used as type id.
1718
class Function {
1819
core.bool operator ==(core.Object other) => false;
1920
}
2021

21-
main() {}
22+
main() {}

pkg/front_end/testcases/general/ignore_function.dart.weak.expect

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/ignore_function.dart:18:7: Error: 'Function' is a built-in identifier, could not used as a class name.
6+
// class Function {
7+
// ^^^^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

pkg/front_end/testcases/general/ignore_function.dart.weak.outline.expect

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/ignore_function.dart:18:7: Error: 'Function' is a built-in identifier, could not used as a class name.
6+
// class Function {
7+
// ^^^^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

pkg/front_end/testcases/general/ignore_function.dart.weak.transformed.expect

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/ignore_function.dart:18:7: Error: 'Function' is a built-in identifier, could not used as a class name.
6+
// class Function {
7+
// ^^^^^^^^
8+
//
29
import self as self;
310
import "dart:core" as core;
411

0 commit comments

Comments
 (0)