@@ -978,16 +978,22 @@ private void inferParameterAndReturnTypesOfClosureOnRHS(final ClassNode lhsType,
978
978
if (parameter .isDynamicTyped ()) {
979
979
parameter .setType (samParameterTypes [i ]);
980
980
parameter .setOriginType (samParameterTypes [i ]);
981
+ } else {
982
+ checkParamType (parameter , samParameterTypes [i ], i == n -1 , rhsExpression instanceof LambdaExpression );
981
983
}
982
984
}
983
985
} else {
984
- String descriptor = toMethodParametersString (findSAM (lhsType ).getName (), samParameterTypes );
985
- addStaticTypeError ("Wrong number of parameters for method target " + descriptor , rhsExpression );
986
+ addStaticTypeError ("Wrong number of parameters for method target " + toMethodParametersString (findSAM (lhsType ).getName (), samParameterTypes ), rhsExpression );
986
987
}
987
988
988
989
storeInferredReturnType (rhsExpression , typeInfo .getV2 ());
989
990
}
990
991
992
+ private void checkParamType (final Parameter source , final ClassNode target , final boolean isLast , final boolean lambda ) {
993
+ if (/*lambda ? !source.getOriginType().equals(target) :*/ !typeCheckMethodArgumentWithGenerics (source .getOriginType (), target , isLast ))
994
+ addStaticTypeError ("Expected type " + prettyPrintType (target ) + " for " + (lambda ? "lambda" : "closure" ) + " parameter: " + source .getName (), source );
995
+ }
996
+
991
997
/**
992
998
* Given a binary expression corresponding to an assignment, will check that
993
999
* the type of the RHS matches one of the possible setters and if not, throw
@@ -2405,38 +2411,22 @@ public void visitClosureExpression(final ClosureExpression expression) {
2405
2411
// perform visit
2406
2412
typeCheckingContext .pushEnclosingClosureExpression (expression );
2407
2413
DelegationMetadata dmd = getDelegationMetadata (expression );
2408
- if (dmd == null ) {
2409
- typeCheckingContext .delegationMetadata = new DelegationMetadata (
2410
- typeCheckingContext .getEnclosingClassNode (), Closure .OWNER_FIRST , typeCheckingContext .delegationMetadata
2411
- );
2414
+ if (dmd != null ) {
2415
+ typeCheckingContext .delegationMetadata = newDelegationMetadata (dmd .getType (), dmd .getStrategy ());
2412
2416
} else {
2413
- typeCheckingContext .delegationMetadata = new DelegationMetadata (
2414
- dmd .getType (),
2415
- dmd .getStrategy (),
2416
- typeCheckingContext .delegationMetadata
2417
- );
2417
+ typeCheckingContext .delegationMetadata = newDelegationMetadata (typeCheckingContext .getEnclosingClassNode (), Closure .OWNER_FIRST );
2418
2418
}
2419
2419
super .visitClosureExpression (expression );
2420
2420
typeCheckingContext .delegationMetadata = typeCheckingContext .delegationMetadata .getParent ();
2421
- MethodNode node = new MethodNode ("dummy" , 0 , OBJECT_TYPE , Parameter .EMPTY_ARRAY , ClassNode .EMPTY_ARRAY , expression .getCode ());
2422
- returnAdder .visitMethod (node );
2423
2421
2424
- TypeCheckingContext .EnclosingClosure enclosingClosure = typeCheckingContext .getEnclosingClosure ();
2425
- if (!enclosingClosure .getReturnTypes ().isEmpty ()) {
2422
+ returnAdder .visitMethod (new MethodNode ("dummy" , 0 , OBJECT_TYPE , Parameter .EMPTY_ARRAY , ClassNode .EMPTY_ARRAY , expression .getCode ()));
2423
+ TypeCheckingContext .EnclosingClosure enclosingClosure = typeCheckingContext .popEnclosingClosure ();
2424
+ if (!enclosingClosure .getReturnTypes ().isEmpty ()) { // populated by ReturnAdder
2426
2425
ClassNode returnType = lowestUpperBound (enclosingClosure .getReturnTypes ());
2427
-
2428
- ClassNode expectedReturnType = getInferredReturnType (expression );
2429
- // type argument can not be of primitive type, we should convert it to the wrapper type
2430
- if (expectedReturnType != null && isPrimitiveType (returnType ) && expectedReturnType .equals (getWrapper (returnType ))) {
2431
- returnType = expectedReturnType ;
2432
- }
2433
-
2434
- storeInferredReturnType (expression , returnType );
2435
- ClassNode inferredType = wrapClosureType (returnType );
2436
- storeType (enclosingClosure .getClosureExpression (), inferredType );
2426
+ storeInferredReturnType (expression , wrapTypeIfNecessary (returnType ));
2427
+ storeType (expression , wrapClosureType (returnType ));
2437
2428
}
2438
2429
2439
- typeCheckingContext .popEnclosingClosure ();
2440
2430
// check types of closure shared variables for change
2441
2431
if (isSecondPassNeededForControlStructure (varTypes , oldTracker )) {
2442
2432
visitClosureExpression (expression );
@@ -2518,6 +2508,10 @@ protected DelegationMetadata getDelegationMetadata(final ClosureExpression expre
2518
2508
return expression .getNodeMetaData (DELEGATION_METADATA );
2519
2509
}
2520
2510
2511
+ private DelegationMetadata newDelegationMetadata (final ClassNode delegateType , final int resolveStrategy ) {
2512
+ return new DelegationMetadata (delegateType , resolveStrategy , typeCheckingContext .delegationMetadata );
2513
+ }
2514
+
2521
2515
protected void restoreVariableExpressionMetadata (final Map <VariableExpression , Map <StaticTypesMarker , Object >> typesBeforeVisit ) {
2522
2516
if (typesBeforeVisit != null ) {
2523
2517
typesBeforeVisit .forEach ((var , map ) -> {
@@ -2759,11 +2753,7 @@ protected void checkClosureParameters(final Expression callArguments, final Clas
2759
2753
addStaticTypeError ("Expected parameter type: " + prettyPrintType (receiver ) + " but was: " + prettyPrintType (param .getType ()), param );
2760
2754
}
2761
2755
}
2762
- closure .putNodeMetaData (DELEGATION_METADATA , new DelegationMetadata (
2763
- receiver ,
2764
- Closure .DELEGATE_FIRST ,
2765
- typeCheckingContext .delegationMetadata
2766
- ));
2756
+ closure .putNodeMetaData (DELEGATION_METADATA , newDelegationMetadata (receiver , Closure .DELEGATE_FIRST ));
2767
2757
}
2768
2758
}
2769
2759
@@ -2982,9 +2972,9 @@ protected void inferClosureParameterTypes(final ClassNode receiver, final Expres
2982
2972
// implicit parameter(s)
2983
2973
paramTypes = samParamTypes ;
2984
2974
} else {
2985
- paramTypes = new ClassNode [ n ] ;
2986
- for (int i = 0 ; i < n ; i += 1 ) {
2987
- paramTypes [i ] = i < samParamTypes . length ? samParamTypes [ i ] : null ;
2975
+ paramTypes = Arrays . copyOf ( samParamTypes , n ) ;
2976
+ for (int i = 0 ; i < Math . min ( n , samParamTypes . length ) ; i += 1 ) {
2977
+ checkParamType ( p [ i ], paramTypes [i ], i == n - 1 , expression instanceof LambdaExpression ) ;
2988
2978
}
2989
2979
}
2990
2980
expression .putNodeMetaData (CLOSURE_ARGUMENTS , paramTypes );
@@ -3055,25 +3045,24 @@ private void doInferClosureParameterTypes(final ClassNode receiver, final Expres
3055
3045
}
3056
3046
}
3057
3047
if (candidates .size () > 1 ) {
3058
- Iterator <ClassNode []> candIt = candidates .iterator ();
3059
- while (candIt .hasNext ()) {
3048
+ for (Iterator <ClassNode []> candIt = candidates .iterator (); candIt .hasNext (); ) {
3060
3049
ClassNode [] inferred = candIt .next ();
3061
3050
for (int i = 0 , n = closureParams .length ; i < n ; i += 1 ) {
3062
3051
Parameter closureParam = closureParams [i ];
3063
- ClassNode originType = closureParam .getOriginType ();
3052
+ ClassNode declaredType = closureParam .getOriginType ();
3064
3053
ClassNode inferredType ;
3065
- if (i < inferred .length - 1 || inferred .length == closureParams . length ) {
3054
+ if (i < inferred .length - 1 || inferred .length == n ) {
3066
3055
inferredType = inferred [i ];
3067
- } else { // vargs?
3068
- ClassNode lastArgInferred = inferred [inferred .length - 1 ];
3069
- if (lastArgInferred .isArray ()) {
3070
- inferredType = lastArgInferred .getComponentType ();
3056
+ } else {
3057
+ ClassNode lastInferred = inferred [inferred .length - 1 ];
3058
+ if (lastInferred .isArray ()) {
3059
+ inferredType = lastInferred .getComponentType ();
3071
3060
} else {
3072
3061
candIt .remove ();
3073
3062
continue ;
3074
3063
}
3075
3064
}
3076
- if (!typeCheckMethodArgumentWithGenerics (originType , inferredType , i == (n - 1 ))) {
3065
+ if (!typeCheckMethodArgumentWithGenerics (declaredType , inferredType , i == (n - 1 ))) {
3077
3066
candIt .remove ();
3078
3067
}
3079
3068
}
@@ -3092,24 +3081,19 @@ private void doInferClosureParameterTypes(final ClassNode receiver, final Expres
3092
3081
} else {
3093
3082
for (int i = 0 , n = closureParams .length ; i < n ; i += 1 ) {
3094
3083
Parameter closureParam = closureParams [i ];
3095
- ClassNode originType = closureParam .getOriginType ();
3084
+ ClassNode declaredType = closureParam .getOriginType ();
3096
3085
ClassNode inferredType = OBJECT_TYPE ;
3097
- if (i < inferred .length - 1 || inferred .length == closureParams . length ) {
3086
+ if (i < inferred .length - 1 || inferred .length == n ) {
3098
3087
inferredType = inferred [i ];
3099
- } else { // vargs?
3100
- ClassNode lastArgInferred = inferred [inferred .length - 1 ];
3101
- if (lastArgInferred .isArray ()) {
3102
- inferredType = lastArgInferred .getComponentType ();
3088
+ } else {
3089
+ ClassNode lastInferred = inferred [inferred .length - 1 ];
3090
+ if (lastInferred .isArray ()) {
3091
+ inferredType = lastInferred .getComponentType ();
3103
3092
} else {
3104
- addError ("Incorrect number of parameters. Expected " + inferred .length + " but found " + closureParams . length , expression );
3093
+ addError ("Incorrect number of parameters. Expected " + inferred .length + " but found " + n , expression );
3105
3094
}
3106
3095
}
3107
- boolean lastArg = i == (n - 1 );
3108
-
3109
- if (!typeCheckMethodArgumentWithGenerics (originType , inferredType , lastArg )) {
3110
- addError ("Expected parameter of type " + prettyPrintType (inferredType ) + " but got " + prettyPrintType (originType ), closureParam .getType ());
3111
- }
3112
-
3096
+ checkParamType (closureParam , inferredType , i == n -1 , false );
3113
3097
typeCheckingContext .controlStructureVariables .put (closureParam , inferredType );
3114
3098
}
3115
3099
}
@@ -3191,7 +3175,7 @@ private void checkClosureWithDelegatesTo(final ClassNode receiver, final MethodN
3191
3175
+ ") without @DelegatesTo.Target because generic argument types are not available at runtime" , value );
3192
3176
}
3193
3177
// temporarily store the delegation strategy and the delegate type
3194
- expression .putNodeMetaData (DELEGATION_METADATA , new DelegationMetadata (value .getType (), stInt , typeCheckingContext . delegationMetadata ));
3178
+ expression .putNodeMetaData (DELEGATION_METADATA , newDelegationMetadata (value .getType (), stInt ));
3195
3179
} else if (type != null && !"" .equals (type .getText ()) && type instanceof ConstantExpression ) {
3196
3180
String typeString = type .getText ();
3197
3181
ClassNode [] resolved = GenericsUtils .parseClassNodesFromString (
@@ -3204,7 +3188,7 @@ private void checkClosureWithDelegatesTo(final ClassNode receiver, final MethodN
3204
3188
if (resolved != null ) {
3205
3189
if (resolved .length == 1 ) {
3206
3190
resolved = resolveGenericsFromTypeHint (receiver , arguments , mn , resolved );
3207
- expression .putNodeMetaData (DELEGATION_METADATA , new DelegationMetadata (resolved [0 ], stInt , typeCheckingContext . delegationMetadata ));
3191
+ expression .putNodeMetaData (DELEGATION_METADATA , newDelegationMetadata (resolved [0 ], stInt ));
3208
3192
} else {
3209
3193
addStaticTypeError ("Incorrect type hint found in method " + (mn ), type );
3210
3194
}
@@ -3246,7 +3230,7 @@ private void checkClosureWithDelegatesTo(final ClassNode receiver, final MethodN
3246
3230
}
3247
3231
}
3248
3232
}
3249
- expression .putNodeMetaData (DELEGATION_METADATA , new DelegationMetadata (actualType , stInt , typeCheckingContext . delegationMetadata ));
3233
+ expression .putNodeMetaData (DELEGATION_METADATA , newDelegationMetadata (actualType , stInt ));
3250
3234
break ;
3251
3235
}
3252
3236
}
0 commit comments