@@ -978,16 +978,22 @@ private void inferParameterAndReturnTypesOfClosureOnRHS(final ClassNode lhsType,
978978 if (parameter .isDynamicTyped ()) {
979979 parameter .setType (samParameterTypes [i ]);
980980 parameter .setOriginType (samParameterTypes [i ]);
981+ } else {
982+ checkParamType (parameter , samParameterTypes [i ], i == n -1 , rhsExpression instanceof LambdaExpression );
981983 }
982984 }
983985 } 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 );
986987 }
987988
988989 storeInferredReturnType (rhsExpression , typeInfo .getV2 ());
989990 }
990991
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+
991997 /**
992998 * Given a binary expression corresponding to an assignment, will check that
993999 * 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) {
24052411 // perform visit
24062412 typeCheckingContext .pushEnclosingClosureExpression (expression );
24072413 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 ());
24122416 } 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 );
24182418 }
24192419 super .visitClosureExpression (expression );
24202420 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 );
24232421
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
24262425 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 ));
24372428 }
24382429
2439- typeCheckingContext .popEnclosingClosure ();
24402430 // check types of closure shared variables for change
24412431 if (isSecondPassNeededForControlStructure (varTypes , oldTracker )) {
24422432 visitClosureExpression (expression );
@@ -2518,6 +2508,10 @@ protected DelegationMetadata getDelegationMetadata(final ClosureExpression expre
25182508 return expression .getNodeMetaData (DELEGATION_METADATA );
25192509 }
25202510
2511+ private DelegationMetadata newDelegationMetadata (final ClassNode delegateType , final int resolveStrategy ) {
2512+ return new DelegationMetadata (delegateType , resolveStrategy , typeCheckingContext .delegationMetadata );
2513+ }
2514+
25212515 protected void restoreVariableExpressionMetadata (final Map <VariableExpression , Map <StaticTypesMarker , Object >> typesBeforeVisit ) {
25222516 if (typesBeforeVisit != null ) {
25232517 typesBeforeVisit .forEach ((var , map ) -> {
@@ -2759,11 +2753,7 @@ protected void checkClosureParameters(final Expression callArguments, final Clas
27592753 addStaticTypeError ("Expected parameter type: " + prettyPrintType (receiver ) + " but was: " + prettyPrintType (param .getType ()), param );
27602754 }
27612755 }
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 ));
27672757 }
27682758 }
27692759
@@ -2982,9 +2972,9 @@ protected void inferClosureParameterTypes(final ClassNode receiver, final Expres
29822972 // implicit parameter(s)
29832973 paramTypes = samParamTypes ;
29842974 } 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 ) ;
29882978 }
29892979 }
29902980 expression .putNodeMetaData (CLOSURE_ARGUMENTS , paramTypes );
@@ -3055,25 +3045,24 @@ private void doInferClosureParameterTypes(final ClassNode receiver, final Expres
30553045 }
30563046 }
30573047 if (candidates .size () > 1 ) {
3058- Iterator <ClassNode []> candIt = candidates .iterator ();
3059- while (candIt .hasNext ()) {
3048+ for (Iterator <ClassNode []> candIt = candidates .iterator (); candIt .hasNext (); ) {
30603049 ClassNode [] inferred = candIt .next ();
30613050 for (int i = 0 , n = closureParams .length ; i < n ; i += 1 ) {
30623051 Parameter closureParam = closureParams [i ];
3063- ClassNode originType = closureParam .getOriginType ();
3052+ ClassNode declaredType = closureParam .getOriginType ();
30643053 ClassNode inferredType ;
3065- if (i < inferred .length - 1 || inferred .length == closureParams . length ) {
3054+ if (i < inferred .length - 1 || inferred .length == n ) {
30663055 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 ();
30713060 } else {
30723061 candIt .remove ();
30733062 continue ;
30743063 }
30753064 }
3076- if (!typeCheckMethodArgumentWithGenerics (originType , inferredType , i == (n - 1 ))) {
3065+ if (!typeCheckMethodArgumentWithGenerics (declaredType , inferredType , i == (n - 1 ))) {
30773066 candIt .remove ();
30783067 }
30793068 }
@@ -3092,24 +3081,19 @@ private void doInferClosureParameterTypes(final ClassNode receiver, final Expres
30923081 } else {
30933082 for (int i = 0 , n = closureParams .length ; i < n ; i += 1 ) {
30943083 Parameter closureParam = closureParams [i ];
3095- ClassNode originType = closureParam .getOriginType ();
3084+ ClassNode declaredType = closureParam .getOriginType ();
30963085 ClassNode inferredType = OBJECT_TYPE ;
3097- if (i < inferred .length - 1 || inferred .length == closureParams . length ) {
3086+ if (i < inferred .length - 1 || inferred .length == n ) {
30983087 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 ();
31033092 } 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 );
31053094 }
31063095 }
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 );
31133097 typeCheckingContext .controlStructureVariables .put (closureParam , inferredType );
31143098 }
31153099 }
@@ -3191,7 +3175,7 @@ private void checkClosureWithDelegatesTo(final ClassNode receiver, final MethodN
31913175 + ") without @DelegatesTo.Target because generic argument types are not available at runtime" , value );
31923176 }
31933177 // 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 ));
31953179 } else if (type != null && !"" .equals (type .getText ()) && type instanceof ConstantExpression ) {
31963180 String typeString = type .getText ();
31973181 ClassNode [] resolved = GenericsUtils .parseClassNodesFromString (
@@ -3204,7 +3188,7 @@ private void checkClosureWithDelegatesTo(final ClassNode receiver, final MethodN
32043188 if (resolved != null ) {
32053189 if (resolved .length == 1 ) {
32063190 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 ));
32083192 } else {
32093193 addStaticTypeError ("Incorrect type hint found in method " + (mn ), type );
32103194 }
@@ -3246,7 +3230,7 @@ private void checkClosureWithDelegatesTo(final ClassNode receiver, final MethodN
32463230 }
32473231 }
32483232 }
3249- expression .putNodeMetaData (DELEGATION_METADATA , new DelegationMetadata (actualType , stInt , typeCheckingContext . delegationMetadata ));
3233+ expression .putNodeMetaData (DELEGATION_METADATA , newDelegationMetadata (actualType , stInt ));
32503234 break ;
32513235 }
32523236 }
0 commit comments