Skip to content

Commit

Permalink
GROOVY-11399: STC: getDelegate(), getOwner(), getThisObject() type
Browse files Browse the repository at this point in the history
4_0_X backport
  • Loading branch information
eric-milles committed Jun 5, 2024
1 parent e9f3204 commit 4b042ef
Show file tree
Hide file tree
Showing 6 changed files with 444 additions and 473 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -601,26 +601,26 @@ public void visitVariableExpression(final VariableExpression vexp) {
case "delegate":
DelegationMetadata dm = getDelegationMetadata(enclosingClosure.getClosureExpression());
if (dm != null) {
storeType(vexp, dm.getType());
vexp.putNodeMetaData(INFERRED_TYPE, dm.getType());
return;
}
// falls through
case "owner":
if (typeCheckingContext.getEnclosingClosureStack().size() > 1) {
storeType(vexp, CLOSURE_TYPE);
vexp.putNodeMetaData(INFERRED_TYPE, CLOSURE_TYPE.getPlainNodeReference());
return;
}
// falls through
case "thisObject":
storeType(vexp, typeCheckingContext.getEnclosingClassNode());
vexp.putNodeMetaData(INFERRED_TYPE, makeThis());
return;
case "parameterTypes":
storeType(vexp, CLASS_Type.makeArray());
vexp.putNodeMetaData(INFERRED_TYPE, CLASS_Type.getPlainNodeReference().makeArray());
return;
case "maximumNumberOfParameters":
case "resolveStrategy":
case "directive":
storeType(vexp, int_TYPE);
vexp.putNodeMetaData(INFERRED_TYPE, int_TYPE);
return;
}
}
Expand Down Expand Up @@ -3611,6 +3611,7 @@ public void visitMethodCallExpression(final MethodCallExpression call) {
if (mn.isEmpty() && isThisObjectExpression && call.isImplicitThis() && typeCheckingContext.getEnclosingClosure() != null) {
mn = CLOSURE_TYPE.getDeclaredMethods(name);
if (!mn.isEmpty()) {
receiver = CLOSURE_TYPE.getPlainNodeReference();
objectExpression.removeNodeMetaData(INFERRED_TYPE);
}
}
Expand Down Expand Up @@ -3661,20 +3662,31 @@ && isClassType(receiver) && chosenReceiver.getData() == null && !Boolean.TRUE.eq
visitMethodCallArguments(chosenReceiver.getType(), argumentList, true, targetMethodCandidate); callArgsVisited = true;

ClassNode returnType = getType(targetMethodCandidate);
if (isUsingGenericsOrIsArrayUsingGenerics(returnType)) {
// GROOVY-5470, GROOVY-6091, GROOVY-9604, GROOVY-11399:
if (isThisObjectExpression && call.isImplicitThis() && typeCheckingContext.getEnclosingClosure() != null
&& (targetMethodCandidate == GET_DELEGATE || targetMethodCandidate == GET_OWNER || targetMethodCandidate == GET_THISOBJECT)) {
switch (name) {
case "getDelegate":
DelegationMetadata dm = getDelegationMetadata(typeCheckingContext.getEnclosingClosure().getClosureExpression());
if (dm != null) {
returnType = dm.getType();
break;
}
// falls through
case "getOwner":
if (typeCheckingContext.getEnclosingClosureStack().size() > 1) {
returnType = CLOSURE_TYPE.getPlainNodeReference();
break;
}
// falls through
case "getThisObject":
returnType = makeThis();
}
} else if (isUsingGenericsOrIsArrayUsingGenerics(returnType)) {
ClassNode irtg = inferReturnTypeGenerics(chosenReceiver.getType(), targetMethodCandidate, callArguments, call.getGenericsTypes());
if (irtg != null && implementsInterfaceOrIsSubclassOf(irtg, returnType))
returnType = irtg;
}
// GROOVY-6091: use of "delegate" or "getDelegate()" does not make use of @DelegatesTo metadata
if (targetMethodCandidate == GET_DELEGATE && typeCheckingContext.getEnclosingClosure() != null) {
DelegationMetadata md = getDelegationMetadata(typeCheckingContext.getEnclosingClosure().getClosureExpression());
if (md != null) {
returnType = md.getType();
} else {
returnType = typeCheckingContext.getEnclosingClassNode();
}
}
// GROOVY-7106, GROOVY-7274, GROOVY-8909, GROOVY-8961, GROOVY-9734, GROOVY-9844, GROOVY-9915, et al.
Parameter[] parameters = targetMethodCandidate.getParameters();
if (chosenReceiver.getType().getGenericsTypes() != null && !targetMethodCandidate.isStatic() && !(targetMethodCandidate instanceof ExtensionMethodNode)) {
Expand Down Expand Up @@ -5240,10 +5252,6 @@ protected ClassNode getType(final ASTNode node) {
}

if (node instanceof MethodNode) {
if ((node == GET_DELEGATE || node == GET_OWNER || node == GET_THISOBJECT)
&& typeCheckingContext.getEnclosingClosure() != null) {
return typeCheckingContext.getEnclosingClassNode();
}
type = ((MethodNode) node).getReturnType();
return Optional.ofNullable(getInferredReturnType(node)).orElse(type);
}
Expand Down
Loading

0 comments on commit 4b042ef

Please sign in to comment.