Skip to content

Commit 0b1d279

Browse files
committed
GROOVY-10372
1 parent 0d5285f commit 0b1d279

File tree

2 files changed

+47
-63
lines changed

2 files changed

+47
-63
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/StaticCompilationTests.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -5895,8 +5895,8 @@ public void testCompileStatic9881() {
58955895
"Main.groovy",
58965896
"@groovy.transform.CompileStatic\n" +
58975897
"void test() {\n" +
5898-
" print new Value(123).replace { -> 'foo' }\n" +
5899-
" print new Value(123).replace { Integer v -> 'bar' }\n" +
5898+
" print new Value<>(123).replace { -> 'foo' }\n" +
5899+
" print new Value<>(123).replace { Integer v -> 'bar' }\n" +
59005900
"}\n" +
59015901
"test()\n",
59025902

@@ -5932,8 +5932,8 @@ public void testCompileStatic9881a() {
59325932
"Main.groovy",
59335933
"@groovy.transform.CompileStatic\n" +
59345934
"void test() {\n" +
5935-
" print new Value(123).replace(() -> 'foo')\n" +
5936-
" print new Value(123).replace((Integer v) -> 'bar')\n" +
5935+
" print new Value<>(123).replace(() -> 'foo')\n" +
5936+
" print new Value<>(123).replace((Integer v) -> 'bar')\n" +
59375937
"}\n" +
59385938
"test()\n",
59395939

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

+43-59
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)