You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/12/18 16:51:51 UTC
[groovy] branch master updated: minor refactor
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new d214c7bb5a minor refactor
d214c7bb5a is described below
commit d214c7bb5ab0b9449f474b57dfc85c5a547369d4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Dec 18 10:24:24 2022 -0600
minor refactor
---
.../transform/stc/StaticTypeCheckingVisitor.java | 69 +++++++++++-----------
1 file changed, 34 insertions(+), 35 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index ebdcb5639d..88f765dda5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1044,22 +1044,12 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
// but we must check if the binary expression is an assignment
// because we need to check if a setter uses @DelegatesTo
VariableExpression receiver = varX("%", setterInfo.receiverType);
- // for "x op= y" expression, find type as if it was "x = x op y"
- Expression valueExpression = rightExpression;
- if (isCompoundAssignment(expression)) {
- Token op = ((BinaryExpression) expression).getOperation();
- if (op.getType() == ELVIS_EQUAL) { // GROOVY-10419: "x ?= y"
- valueExpression = elvisX(leftExpression, rightExpression);
- } else {
- op = Token.newSymbol(TokenUtil.removeAssignment(op.getType()), op.getStartLine(), op.getStartColumn());
- valueExpression = binX(leftExpression, op, rightExpression);
- }
- }
+ receiver.setType(setterInfo.receiverType); // same as origin type
- Function<Expression, MethodNode> setterCall = right -> {
+ Function<Expression, MethodNode> setterCall = (value) -> {
typeCheckingContext.pushEnclosingBinaryExpression(null); // GROOVY-10628: LHS re-purposed
try {
- MethodCallExpression call = new MethodCallExpression(receiver, setterInfo.name, right);
+ MethodCallExpression call = callX(receiver, setterInfo.name, value);
call.setImplicitThis(false);
visitMethodCallExpression(call);
return call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
@@ -1068,7 +1058,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
};
- Function<MethodNode, ClassNode> setterType = setter -> {
+ Function<MethodNode, ClassNode> setterType = (setter) -> {
ClassNode type = setter.getParameters()[0].getOriginType();
if (!setter.isStatic() && !(setter instanceof ExtensionMethodNode) && GenericsUtils.hasUnresolvedGenerics(type)) {
type = applyGenericsContext(extractPlaceHolders(setterInfo.receiverType, setter.getDeclaringClass()), type);
@@ -1076,6 +1066,18 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
return type;
};
+ Expression valueExpression = rightExpression;
+ // for "x op= y", find type as if it was "x = x op y"
+ if (isCompoundAssignment(expression)) {
+ Token op = ((BinaryExpression) expression).getOperation();
+ if (op.getType() == ELVIS_EQUAL) { // GROOVY-10419: "x ?= y"
+ valueExpression = elvisX(leftExpression, rightExpression);
+ } else {
+ op = Token.newSymbol(TokenUtil.removeAssignment(op.getType()), op.getStartLine(), op.getStartColumn());
+ valueExpression = binX(leftExpression, op, rightExpression);
+ }
+ }
+
MethodNode methodTarget = setterCall.apply(valueExpression);
if (methodTarget == null && !isCompoundAssignment(expression)) {
// if no direct match, try implicit conversion
@@ -2742,13 +2744,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
ClassNode[] args = getArgumentTypes(argumentList);
List<MethodNode> mn = findMethod(type, name, args);
- if (!mn.isEmpty()) {
- if (mn.size() == 1) {
- // GROOVY-8909, GROOVY-8961, GROOVY-9734, GROOVY-9844, GROOVY-9915, et al.
- resolvePlaceholdersFromImplicitTypeHints(args, argumentList, mn.get(0).getParameters());
- typeCheckMethodsWithGenericsOrFail(type, args, mn.get(0), call);
- }
- }
if (mn.isEmpty()) {
mn = extension.handleMissingMethod(type, name, argumentList, args, call);
}
@@ -2759,26 +2754,30 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
if (mn.size() != 1) {
addAmbiguousErrorMessage(mn, name, args, call);
} else {
- MethodNode directMethodCallCandidate = mn.get(0);
- ClassNode returnType = getType(directMethodCallCandidate);
+ MethodNode targetMethod = mn.get(0);
+ // GROOVY-8909, GROOVY-8961, GROOVY-9734, GROOVY-9844, GROOVY-9915, et al.
+ resolvePlaceholdersFromImplicitTypeHints(args, argumentList, targetMethod.getParameters());
+ typeCheckMethodsWithGenericsOrFail(type, args, targetMethod, call);
+
+ ClassNode returnType = getType(targetMethod);
if (returnType.isUsingGenerics() && !returnType.isEnum()) {
closuresVisited = true; // visit closure/lambda arguments with selected method
- visitMethodCallArguments(type, argumentList, true, directMethodCallCandidate);
+ visitMethodCallArguments(type, argumentList, true, targetMethod);
- ClassNode rt = inferReturnTypeGenerics(type, directMethodCallCandidate, argumentList);
+ ClassNode rt = inferReturnTypeGenerics(type, targetMethod, argumentList);
if (rt != null && implementsInterfaceOrIsSubclassOf(rt, returnType))
returnType = rt;
}
storeType(call, returnType);
- storeTargetMethod(call, directMethodCallCandidate);
+ storeTargetMethod(call, targetMethod);
}
}
- MethodNode target = call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
if (!closuresVisited) {
- visitMethodCallArguments(type, argumentList, true, target);
+ final MethodNode targetMethod = !mn.isEmpty() ? mn.get(0) : null;
+ visitMethodCallArguments(type, argumentList, true, targetMethod);
}
- if (target != null) { Parameter[] params = target.getParameters();
+ if (mn.size() == 1) { Parameter[] params = mn.get(0).getParameters();
checkClosureMetadata(argumentList.getExpressions(), params);
checkForbiddenSpreadArgument(argumentList, params);
} else {
@@ -5394,25 +5393,25 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
/**
* Given method call like "m(Collections.emptyList())", the type of the call
- * argument is {@code List<T>} without explicit type arguments. Knowing the
- * method target of "m", {@code T} could be resolved.
+ * argument is {@code List<T>} without explicit type arguments. Now, knowing
+ * the method target of "m", {@code T} could be resolved.
*/
private void resolvePlaceholdersFromImplicitTypeHints(final ClassNode[] actuals, final ArgumentListExpression argumentList, final Parameter[] parameterArray) {
int np = parameterArray.length;
for (int i = 0, n = actuals.length; np > 0 && i < n; i += 1) {
- Expression a = argumentList.getExpression(i);
Parameter p = parameterArray[Math.min(i, np - 1)];
-
- ClassNode at = actuals[i], pt = p.getOriginType();
+ ClassNode pt = p.getOriginType(), at = actuals[i];
if (!isUsingGenericsOrIsArrayUsingGenerics(pt)) continue;
if (i >= (np - 1) && pt.isArray() && !at.isArray()) pt = pt.getComponentType();
+ var a = argumentList.getExpression(i);
+
if (a instanceof ListExpression) {
actuals[i] = getLiteralResultType(pt, at, ArrayList_TYPE);
} else if (a instanceof MapExpression) {
actuals[i] = getLiteralResultType(pt, at, LinkedHashMap_TYPE);
} else if (a instanceof ConstructorCallExpression) {
- inferDiamondType((ConstructorCallExpression) a, pt); // GROOVY-10086
+ inferDiamondType((ConstructorCallExpression) a, pt); // GROOVY-8974, GROOVY-9983, GROOVY-10086, et al.
} else if (a instanceof TernaryExpression && at.getGenericsTypes() != null && at.getGenericsTypes().length == 0) {
// GROOVY-9983: double diamond scenario -- "m(flag ? new Type<>(...) : new Type<>(...))"
typeCheckingContext.pushEnclosingBinaryExpression(assignX(varX(p), a, a));