@@ -682,27 +682,37 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
682
682
if (functionResult == null ) {
683
683
return functionResult;
684
684
}
685
+
686
+ // Report an error if any of the _inferred_ type argument types refer to a
687
+ // type parameter. If, however, `node.typeArguments` is not `null`, then
688
+ // any type parameters contained therein are reported as non-constant in
689
+ // [ConstantVerifier].
690
+ if (node.typeArguments == null &&
691
+ (node.typeArgumentTypes? .any (hasTypeParameterReference) ?? false )) {
692
+ _error (node, null );
693
+ }
694
+
685
695
var typeArgumentList = node.typeArguments;
686
696
if (typeArgumentList == null ) {
687
- return functionResult;
688
- } else {
689
- var typeArguments = < DartType > [];
690
- for (var typeArgument in typeArgumentList.arguments) {
691
- var object = typeArgument.accept (this );
692
- if (object == null ) {
693
- return null ;
694
- }
695
- var typeArgumentType = object.toTypeValue ();
696
- if (typeArgumentType == null ) {
697
- return null ;
698
- }
699
- // TODO(srawlins): Test type alias types (`typedef i = int`) used as
700
- // type arguments. Possibly change implementation based on
701
- // canonicalization rules.
702
- typeArguments.add (typeArgumentType);
697
+ return _instantiateFunctionType (node, functionResult);
698
+ }
699
+
700
+ var typeArguments = < DartType > [];
701
+ for (var typeArgument in typeArgumentList.arguments) {
702
+ var object = typeArgument.accept (this );
703
+ if (object == null ) {
704
+ return null ;
703
705
}
704
- return _dartObjectComputer.typeInstantiate (functionResult, typeArguments);
706
+ var typeArgumentType = object.toTypeValue ();
707
+ if (typeArgumentType == null ) {
708
+ return null ;
709
+ }
710
+ // TODO(srawlins): Test type alias types (`typedef i = int`) used as
711
+ // type arguments. Possibly change implementation based on
712
+ // canonicalization rules.
713
+ typeArguments.add (typeArgumentType);
705
714
}
715
+ return _dartObjectComputer.typeInstantiate (functionResult, typeArguments);
706
716
}
707
717
708
718
@override
@@ -1000,7 +1010,7 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
1000
1010
DartObjectImpl ? visitSimpleIdentifier (SimpleIdentifier node) {
1001
1011
var value = _lexicalEnvironment? [node.name];
1002
1012
if (value != null ) {
1003
- return _instantiateFunctionType (node, value);
1013
+ return _instantiateFunctionTypeForSimpleIdentifier (node, value);
1004
1014
}
1005
1015
1006
1016
return _getConstantValue (node, node);
@@ -1212,6 +1222,8 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
1212
1222
var variableElement =
1213
1223
element is PropertyAccessorElement ? element.variable : element;
1214
1224
1225
+ // TODO(srawlins): Remove this check when [FunctionReference]s are inserted
1226
+ // for generic function instantiation for pre-constructor-references code.
1215
1227
if (node is SimpleIdentifier &&
1216
1228
(node.tearOffTypeArgumentTypes? .any (hasTypeParameterReference) ??
1217
1229
false )) {
@@ -1230,7 +1242,7 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
1230
1242
if (value == null ) {
1231
1243
return value;
1232
1244
}
1233
- return _instantiateFunctionType (identifier, value);
1245
+ return _instantiateFunctionTypeForSimpleIdentifier (identifier, value);
1234
1246
}
1235
1247
} else if (variableElement is ConstructorElement ) {
1236
1248
return DartObjectImpl (
@@ -1246,7 +1258,7 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
1246
1258
function.type,
1247
1259
FunctionState (function),
1248
1260
);
1249
- return _instantiateFunctionType (identifier, rawType);
1261
+ return _instantiateFunctionTypeForSimpleIdentifier (identifier, rawType);
1250
1262
}
1251
1263
} else if (variableElement is ClassElement ) {
1252
1264
var type = variableElement.instantiate (
@@ -1305,12 +1317,41 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
1305
1317
return null ;
1306
1318
}
1307
1319
1320
+ /// If the type of [value] is a generic [FunctionType] , and [node] has type
1321
+ /// argument types, returns [value] type-instantiated with those [node] 's
1322
+ /// type argument types, otherwise returns [value] .
1323
+ DartObjectImpl ? _instantiateFunctionType (
1324
+ FunctionReference node, DartObjectImpl value) {
1325
+ var functionElement = value.toFunctionValue ();
1326
+ if (functionElement is ! ExecutableElement ) {
1327
+ return value;
1328
+ }
1329
+ var valueType = functionElement.type;
1330
+ if (valueType.typeFormals.isNotEmpty) {
1331
+ var typeArgumentTypes = node.typeArgumentTypes;
1332
+ if (typeArgumentTypes != null && typeArgumentTypes.isNotEmpty) {
1333
+ var instantiatedType =
1334
+ functionElement.type.instantiate (typeArgumentTypes);
1335
+ var substitution = _substitution;
1336
+ if (substitution != null ) {
1337
+ instantiatedType =
1338
+ substitution.substituteType (instantiatedType) as FunctionType ;
1339
+ }
1340
+ return value.typeInstantiate (
1341
+ typeSystem, instantiatedType, typeArgumentTypes);
1342
+ }
1343
+ }
1344
+ return value;
1345
+ }
1346
+
1308
1347
/// If the type of [value] is a generic [FunctionType] , and [node] is a
1309
1348
/// [SimpleIdentifier] with tear-off type argument types, returns [value]
1310
1349
/// type-instantiated with those [node] 's tear-off type argument types,
1311
1350
/// otherwise returns [value] .
1312
- DartObjectImpl ? _instantiateFunctionType (
1351
+ DartObjectImpl ? _instantiateFunctionTypeForSimpleIdentifier (
1313
1352
SimpleIdentifier node, DartObjectImpl value) {
1353
+ // TODO(srawlins): When all code uses [FunctionReference]s generated via
1354
+ // generic function instantiation, remove this method and all call sites.
1314
1355
var functionElement = value.toFunctionValue ();
1315
1356
if (functionElement is ! ExecutableElement ) {
1316
1357
return value;
0 commit comments