@@ -337,7 +337,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
337
337
protected static final ClassNode ITERABLE_TYPE = ClassHelper .make (Iterable .class );
338
338
private static final ClassNode SET_TYPE = ClassHelper .make (Set .class );
339
339
340
- private static final List <ClassNode > TUPLE_TYPES = Arrays .stream (ClassHelper . TUPLE_CLASSES ).map (ClassHelper ::makeWithoutCaching ).collect (Collectors .toList ());
340
+ private static final List <ClassNode > TUPLE_TYPES = Arrays .stream (TUPLE_CLASSES ).map (ClassHelper ::makeWithoutCaching ).collect (Collectors .toList ());
341
341
342
342
public static final Statement GENERATED_EMPTY_STATEMENT = EmptyStatement .INSTANCE ;
343
343
@@ -655,7 +655,7 @@ public void visitVariableExpression(final VariableExpression vexp) {
655
655
inferredType = getInferredTypeFromTempInfo (localVariable , inferredType );
656
656
if (inferredType != null && !inferredType .equals (OBJECT_TYPE )
657
657
&& !inferredType .equals (accessedVariable .getOriginType ())) {
658
- vexp .putNodeMetaData (INFERRED_RETURN_TYPE , inferredType );
658
+ vexp .putNodeMetaData (INFERRED_TYPE , inferredType );
659
659
}
660
660
}
661
661
}
@@ -764,11 +764,7 @@ public void visitBinaryExpression(final BinaryExpression expression) {
764
764
lType = getType (leftExpression );
765
765
} else {
766
766
if (op != EQUAL && op != ELVIS_EQUAL ) {
767
- if (leftExpression instanceof VariableExpression && hasInferredReturnType (leftExpression )) {
768
- lType = getInferredReturnType (leftExpression ); // GROOVY-10217
769
- } else {
770
- lType = getType (leftExpression );
771
- }
767
+ lType = getType (leftExpression );
772
768
} else {
773
769
lType = getOriginalDeclarationType (leftExpression );
774
770
@@ -1335,23 +1331,17 @@ protected void typeCheckAssignment(final BinaryExpression assignmentExpression,
1335
1331
// TODO: need errors for write-only too!
1336
1332
if (addedReadOnlyPropertyError (leftExpression )) return ;
1337
1333
1338
- ClassNode rTypeInferred ; // see if any instanceof exists
1339
- if (rightExpression instanceof VariableExpression && hasInferredReturnType (rightExpression ) && assignmentExpression .getOperation ().getType () == EQUAL ) {
1340
- rTypeInferred = getInferredReturnType (rightExpression );
1341
- } else {
1342
- rTypeInferred = rightExpressionType ;
1343
- }
1344
- ClassNode rTypeAdjusted = adjustTypeForSpreading (rTypeInferred , leftExpression );
1334
+ ClassNode rTypeAdjusted = adjustTypeForSpreading (rightExpressionType , leftExpression );
1345
1335
1346
1336
if (!checkCompatibleAssignmentTypes (leftExpressionType , rTypeAdjusted , rightExpression )) {
1347
1337
if (!extension .handleIncompatibleAssignment (leftExpressionType , rTypeAdjusted , assignmentExpression )) {
1348
- addAssignmentError (leftExpressionType , rTypeInferred , rightExpression );
1338
+ addAssignmentError (leftExpressionType , rightExpressionType , rightExpression );
1349
1339
}
1350
1340
} else {
1351
1341
ClassNode lTypeRedirect = leftExpressionType .redirect ();
1352
1342
addPrecisionErrors (lTypeRedirect , leftExpressionType , rTypeAdjusted , rightExpression );
1353
1343
if (rightExpression instanceof ListExpression ) {
1354
- addListAssignmentConstructorErrors (lTypeRedirect , leftExpressionType , rTypeInferred , rightExpression , assignmentExpression );
1344
+ addListAssignmentConstructorErrors (lTypeRedirect , leftExpressionType , rightExpressionType , rightExpression , assignmentExpression );
1355
1345
} else if (rightExpression instanceof MapExpression ) {
1356
1346
addMapAssignmentConstructorErrors (lTypeRedirect , leftExpression , (MapExpression )rightExpression );
1357
1347
}
@@ -1999,12 +1989,7 @@ public void visitForLoop(final ForStatement forLoop) {
1999
1989
} else {
2000
1990
visitStatement (forLoop );
2001
1991
collectionExpression .visit (this );
2002
- ClassNode collectionType ;
2003
- if (collectionExpression instanceof VariableExpression && hasInferredReturnType (collectionExpression )) {
2004
- collectionType = getInferredReturnType (collectionExpression );
2005
- } else {
2006
- collectionType = getType (collectionExpression );
2007
- }
1992
+ ClassNode collectionType = getType (collectionExpression );
2008
1993
ClassNode forLoopVariableType = forLoop .getVariableType ();
2009
1994
ClassNode componentType ;
2010
1995
if (Character_TYPE .equals (getWrapper (forLoopVariableType )) && STRING_TYPE .equals (collectionType )) {
@@ -2271,18 +2256,12 @@ private ClassNode infer(final ClassNode target, final ClassNode source) {
2271
2256
2272
2257
protected ClassNode checkReturnType (final ReturnStatement statement ) {
2273
2258
Expression expression = statement .getExpression ();
2274
- ClassNode type ;
2275
- if (expression instanceof VariableExpression && hasInferredReturnType (expression )) {
2276
- type = getInferredReturnType (expression );
2277
- } else {
2278
- type = getType (expression );
2279
- }
2259
+ ClassNode type = getType (expression );
2280
2260
if (typeCheckingContext .getEnclosingClosure () != null ) {
2281
2261
ClassNode inferredReturnType = getInferredReturnType (typeCheckingContext .getEnclosingClosure ().getClosureExpression ());
2282
2262
// GROOVY-9995: return ctor call with diamond operator
2283
2263
if (expression instanceof ConstructorCallExpression ) {
2284
- ClassNode inferredClosureReturnType = getInferredReturnType (typeCheckingContext .getEnclosingClosure ().getClosureExpression ());
2285
- if (inferredClosureReturnType != null ) inferDiamondType ((ConstructorCallExpression ) expression , inferredClosureReturnType );
2264
+ inferDiamondType ((ConstructorCallExpression ) expression , inferredReturnType != null ? inferredReturnType : DYNAMIC_TYPE ); // GROOVY-10080
2286
2265
}
2287
2266
if (inferredReturnType != null && inferredReturnType .equals (STRING_TYPE ) && isGStringOrGStringStringLUB (type )) {
2288
2267
type = STRING_TYPE ; // GROOVY-9971: convert GString to String at point of return
@@ -2419,7 +2398,7 @@ protected MethodNode typeCheckMapConstructor(final ConstructorCallExpression cal
2419
2398
2420
2399
protected ClassNode [] getArgumentTypes (final ArgumentListExpression args ) {
2421
2400
return args .getExpressions ().stream ().map (exp ->
2422
- isNullConstant (exp ) ? UNKNOWN_PARAMETER_TYPE : getInferredTypeFromTempInfo ( exp , getType (exp ) )
2401
+ isNullConstant (exp ) ? UNKNOWN_PARAMETER_TYPE : getType (exp )
2423
2402
).toArray (ClassNode []::new );
2424
2403
}
2425
2404
@@ -3848,11 +3827,7 @@ protected ClassNode getInferredReturnTypeFromWithClosureArgument(final Expressio
3848
3827
3849
3828
visitClosureExpression (closure );
3850
3829
3851
- if (getInferredReturnType (closure ) != null ) {
3852
- return getInferredReturnType (closure );
3853
- }
3854
-
3855
- return null ;
3830
+ return getInferredReturnType (closure );
3856
3831
}
3857
3832
3858
3833
/**
@@ -4328,7 +4303,6 @@ && isOrImplements(typeOfFalse, typeOfTrue))) { // List/Collection/Iterable : []
4328
4303
* @param type the inferred type of {@code expr}
4329
4304
*/
4330
4305
private ClassNode checkForTargetType (final Expression expr , final ClassNode type ) {
4331
- ClassNode sourceType = type ;
4332
4306
ClassNode targetType = null ;
4333
4307
MethodNode enclosingMethod = typeCheckingContext .getEnclosingMethod ();
4334
4308
MethodCall enclosingMethodCall = (MethodCall )typeCheckingContext .getEnclosingMethodCall ();
@@ -4348,27 +4322,15 @@ && isTypeSource(expr, enclosingMethod)) {
4348
4322
targetType = enclosingMethod .getReturnType ();
4349
4323
}
4350
4324
4351
- if (expr instanceof VariableExpression && hasInferredReturnType ( expr )) {
4352
- sourceType = getInferredReturnType ( expr );
4353
- }
4325
+ if (targetType == null )
4326
+ targetType = type . getPlainNodeReference ( );
4327
+ if ( type == UNKNOWN_PARAMETER_TYPE ) return targetType ;
4354
4328
4355
- if (expr instanceof ConstructorCallExpression ) { // GROOVY-9972, GROOVY-9983
4356
- // GROOVY-10114: type parameter(s) could be inferred from call arguments
4357
- if (targetType == null ) targetType = sourceType .getPlainNodeReference ();
4329
+ if (expr instanceof ConstructorCallExpression ) { // GROOVY-9972, GROOVY-9983, GROOVY-10114
4358
4330
inferDiamondType ((ConstructorCallExpression ) expr , targetType );
4359
- return sourceType ;
4360
- }
4361
-
4362
- if (targetType == null ) return sourceType ;
4363
-
4364
- if (!isPrimitiveType (getUnwrapper (targetType )) && !OBJECT_TYPE .equals (targetType )
4365
- && !sourceType .isGenericsPlaceHolder () && missesGenericsTypes (sourceType )) {
4366
- // unchecked assignment with ternary/elvis, like "List<T> list = listOfT ?: []"
4367
- // the inferred type is the RHS type "completed" with generics information from LHS
4368
- return GenericsUtils .parameterizeType (targetType , sourceType .getPlainNodeReference ());
4369
4331
}
4370
4332
4371
- return sourceType != UNKNOWN_PARAMETER_TYPE ? sourceType : targetType ;
4333
+ return adjustForTargetType ( type , targetType ); // GROOVY-10688
4372
4334
}
4373
4335
4374
4336
private static ClassNode adjustForTargetType (final ClassNode resultType , final ClassNode targetType ) {
@@ -4454,11 +4416,6 @@ private static boolean isEmptyCollection(final Expression expr) {
4454
4416
|| (expr instanceof MapExpression && ((MapExpression ) expr ).getMapEntryExpressions ().isEmpty ());
4455
4417
}
4456
4418
4457
- private static boolean hasInferredReturnType (final Expression expression ) {
4458
- ClassNode type = expression .getNodeMetaData (INFERRED_RETURN_TYPE );
4459
- return type != null && !type .getName ().equals (ClassHelper .OBJECT );
4460
- }
4461
-
4462
4419
@ Override
4463
4420
public void visitTryCatchFinally (final TryCatchStatement statement ) {
4464
4421
List <CatchStatement > catchStatements = statement .getCatchStatements ();
@@ -4778,8 +4735,7 @@ protected static ClassNode getGroupOperationResultType(final ClassNode a, final
4778
4735
protected ClassNode inferComponentType (final ClassNode containerType , final ClassNode indexType ) {
4779
4736
ClassNode componentType = containerType .getComponentType ();
4780
4737
if (componentType == null ) {
4781
- // GROOVY-5521
4782
- // try to identify a getAt method
4738
+ // GROOVY-5521: check for "getAt" method
4783
4739
typeCheckingContext .pushErrorCollector ();
4784
4740
MethodCallExpression vcall = callX (localVarX ("_hash_" , containerType ), "getAt" , varX ("_index_" , indexType ));
4785
4741
vcall .setImplicitThis (false ); // GROOVY-8943
@@ -4788,10 +4744,9 @@ protected ClassNode inferComponentType(final ClassNode containerType, final Clas
4788
4744
} finally {
4789
4745
typeCheckingContext .popErrorCollector ();
4790
4746
}
4791
- return getType (vcall );
4792
- } else {
4793
- return componentType ;
4747
+ componentType = getType (vcall );
4794
4748
}
4749
+ return componentType ;
4795
4750
}
4796
4751
4797
4752
protected MethodNode findMethodOrFail (final Expression expr , final ClassNode receiver , final String name , final ClassNode ... args ) {
@@ -5312,14 +5267,14 @@ protected ClassNode storeInferredReturnType(final ASTNode node, final ClassNode
5312
5267
}
5313
5268
5314
5269
/**
5315
- * Returns the inferred return type of a closure or a method, if stored on the AST node. This method
5316
- * doesn't perform any type inference by itself.
5270
+ * Returns the inferred return type of a closure or method, if stored on the
5271
+ * AST node. This method doesn't perform any type inference by itself.
5317
5272
*
5318
- * @param exp a {@link ClosureExpression} or {@link MethodNode}
5319
- * @return the inferred type, as stored on node metadata.
5273
+ * @param node a {@link ClosureExpression} or {@link MethodNode}
5274
+ * @return the expected return type
5320
5275
*/
5321
- protected ClassNode getInferredReturnType (final ASTNode exp ) {
5322
- return exp .getNodeMetaData (INFERRED_RETURN_TYPE );
5276
+ protected ClassNode getInferredReturnType (final ASTNode node ) {
5277
+ return node .getNodeMetaData (INFERRED_RETURN_TYPE );
5323
5278
}
5324
5279
5325
5280
protected ClassNode inferListExpressionType (final ListExpression list ) {
0 commit comments