@@ -6,6 +6,8 @@ library fasta.body_builder;
6
6
7
7
import 'dart:core' hide MapEntry;
8
8
9
+ import 'package:kernel/type_algebra.dart' show containsTypeVariable, substitute;
10
+
9
11
import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart' ;
10
12
11
13
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
@@ -4456,6 +4458,53 @@ class BodyBuilder extends ScopeListener<JumpTarget>
4456
4458
enterFunction ();
4457
4459
}
4458
4460
4461
+ _checkTypeParameters (FunctionNode function) {
4462
+ if (member == null ) return ;
4463
+ if (! member.isStatic) return ;
4464
+ List <TypeParameter > typeParameters;
4465
+ if (member.parent is ClassBuilder ) {
4466
+ ClassBuilder enclosingClassBuilder = member.parent;
4467
+ typeParameters = enclosingClassBuilder.cls.typeParameters;
4468
+ } else if (member.parent is ExtensionBuilder ) {
4469
+ ExtensionBuilder enclosingExtensionBuilder = member.parent;
4470
+ typeParameters = enclosingExtensionBuilder.extension .typeParameters;
4471
+ }
4472
+ if (typeParameters != null && typeParameters.isNotEmpty) {
4473
+ Map <TypeParameter , DartType > substitution;
4474
+ DartType removeTypeVariables (DartType type, int offset) {
4475
+ if (substitution == null ) {
4476
+ substitution = < TypeParameter , DartType > {};
4477
+ for (TypeParameter parameter in typeParameters) {
4478
+ substitution[parameter] = const DynamicType ();
4479
+ }
4480
+ }
4481
+ libraryBuilder.addProblem (fasta.messageNonInstanceTypeVariableUse,
4482
+ offset, noLength, member.fileUri);
4483
+ return substitute (type, substitution);
4484
+ }
4485
+
4486
+ Set <TypeParameter > set = typeParameters.toSet ();
4487
+ for (VariableDeclaration parameter in function.positionalParameters) {
4488
+ parameter.fileOffset;
4489
+ if (containsTypeVariable (parameter.type, set )) {
4490
+ parameter.type =
4491
+ removeTypeVariables (parameter.type, parameter.fileOffset);
4492
+ }
4493
+ }
4494
+ for (VariableDeclaration parameter in function.namedParameters) {
4495
+ if (containsTypeVariable (parameter.type, set )) {
4496
+ parameter.type =
4497
+ removeTypeVariables (parameter.type, parameter.fileOffset);
4498
+ }
4499
+ }
4500
+ if (containsTypeVariable (function.returnType, set )) {
4501
+ // TODO(CFE Team): The offset here doesn't actually point to the type.
4502
+ function.returnType =
4503
+ removeTypeVariables (function.returnType, function.fileOffset);
4504
+ }
4505
+ }
4506
+ }
4507
+
4459
4508
void pushNamedFunction (Token token, bool isFunctionExpression) {
4460
4509
Statement body = popStatement ();
4461
4510
AsyncMarker asyncModifier = pop ();
@@ -4472,6 +4521,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
4472
4521
}
4473
4522
FunctionNode function = formals.buildFunctionNode (libraryBuilder,
4474
4523
returnType, typeParameters, asyncModifier, body, token.charOffset);
4524
+ _checkTypeParameters (function);
4475
4525
4476
4526
if (declaration is FunctionDeclaration ) {
4477
4527
VariableDeclaration variable = declaration.variable;
@@ -4559,6 +4609,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
4559
4609
FunctionNode function = formals.buildFunctionNode (libraryBuilder, null ,
4560
4610
typeParameters, asyncModifier, body, token.charOffset)
4561
4611
..fileOffset = beginToken.charOffset;
4612
+ _checkTypeParameters (function);
4562
4613
4563
4614
Expression result;
4564
4615
if (constantContext != ConstantContext .none) {
@@ -5677,32 +5728,66 @@ class BodyBuilder extends ScopeListener<JumpTarget>
5677
5728
if (builder is NamedTypeBuilder && builder.declaration.isTypeVariable) {
5678
5729
TypeVariableBuilder typeParameterBuilder = builder.declaration;
5679
5730
TypeParameter typeParameter = typeParameterBuilder.parameter;
5680
- LocatedMessage message;
5681
- if (! isDeclarationInstanceContext && typeParameter.parent is Class ) {
5682
- message = fasta.messageTypeVariableInStaticContext.withLocation (
5683
- unresolved.fileUri,
5684
- unresolved.charOffset,
5685
- typeParameter.name.length);
5686
- } else if (constantContext == ConstantContext .inferred) {
5687
- message = fasta.messageTypeVariableInConstantContext.withLocation (
5688
- unresolved.fileUri,
5689
- unresolved.charOffset,
5690
- typeParameter.name.length);
5691
- } else {
5692
- return unresolved;
5693
- }
5694
- addProblem (message.messageObject, message.charOffset, message.length);
5731
+ LocatedMessage message = _validateTypeUseIsInternal (
5732
+ builder, unresolved.fileUri, unresolved.charOffset);
5733
+ if (message == null ) return unresolved;
5695
5734
return new UnresolvedType (
5696
5735
new NamedTypeBuilder (
5697
5736
typeParameter.name, builder.nullabilityBuilder, null )
5698
5737
..bind (
5699
5738
new InvalidTypeDeclarationBuilder (typeParameter.name, message)),
5700
5739
unresolved.charOffset,
5701
5740
unresolved.fileUri);
5741
+ } else if (builder is FunctionTypeBuilder ) {
5742
+ LocatedMessage message = _validateTypeUseIsInternal (
5743
+ builder, unresolved.fileUri, unresolved.charOffset);
5744
+ if (message == null ) return unresolved;
5745
+ // TODO(CFE Team): This should probably be some kind of InvalidType
5746
+ // instead of null.
5747
+ return new UnresolvedType (
5748
+ null , unresolved.charOffset, unresolved.fileUri);
5702
5749
}
5703
5750
return unresolved;
5704
5751
}
5705
5752
5753
+ LocatedMessage _validateTypeUseIsInternal (
5754
+ TypeBuilder builder, Uri fileUri, int charOffset) {
5755
+ if (builder is NamedTypeBuilder && builder.declaration.isTypeVariable) {
5756
+ TypeVariableBuilder typeParameterBuilder = builder.declaration;
5757
+ TypeParameter typeParameter = typeParameterBuilder.parameter;
5758
+ LocatedMessage message;
5759
+ if (! isDeclarationInstanceContext &&
5760
+ (typeParameter.parent is Class ||
5761
+ typeParameter.parent is Extension )) {
5762
+ message = fasta.messageTypeVariableInStaticContext
5763
+ .withLocation (fileUri, charOffset, typeParameter.name.length);
5764
+ } else if (constantContext == ConstantContext .inferred) {
5765
+ message = fasta.messageTypeVariableInConstantContext
5766
+ .withLocation (fileUri, charOffset, typeParameter.name.length);
5767
+ } else {
5768
+ return null ;
5769
+ }
5770
+ addProblem (message.messageObject, message.charOffset, message.length);
5771
+ return message;
5772
+ } else if (builder is FunctionTypeBuilder ) {
5773
+ LocatedMessage result =
5774
+ _validateTypeUseIsInternal (builder.returnType, fileUri, charOffset);
5775
+ if (result != null ) {
5776
+ return result;
5777
+ }
5778
+ if (builder.formals != null ) {
5779
+ for (FormalParameterBuilder formalParameterBuilder in builder.formals) {
5780
+ result = _validateTypeUseIsInternal (
5781
+ formalParameterBuilder.type, fileUri, charOffset);
5782
+ if (result != null ) {
5783
+ return result;
5784
+ }
5785
+ }
5786
+ }
5787
+ }
5788
+ return null ;
5789
+ }
5790
+
5706
5791
@override
5707
5792
Expression evaluateArgumentsBefore (
5708
5793
Arguments arguments, Expression expression) {
0 commit comments