This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY_2_5_X in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 1f86efa7b20bfee67f309c46bf45fab8f58d3aed Author: Eric Milles <[email protected]> AuthorDate: Sat Apr 30 14:34:21 2022 -0500 GROOVY-10598: fix for NPE --- .../transform/stc/StaticTypeCheckingSupport.java | 6 ++--- .../transform/stc/StaticTypeCheckingVisitor.java | 29 ++++++++++++---------- .../codehaus/groovy/transform/trait/Traits.java | 20 +++++++-------- src/spec/test/typing/TypeCheckingTest.groovy | 2 +- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java index 67980dc670..634f685083 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -529,16 +529,16 @@ public abstract class StaticTypeCheckingSupport { switch (op) { case COMPARE_EQUAL: case COMPARE_NOT_EQUAL: - // this is only correct in this context here, normally + // this is only correct in this specific context; normally // we would have to compile against compareTo if available // but since we don't compile here, this one is enough return "equals"; case COMPARE_TO: - case COMPARE_GREATER_THAN: - case COMPARE_GREATER_THAN_EQUAL: case COMPARE_LESS_THAN: case COMPARE_LESS_THAN_EQUAL: + case COMPARE_GREATER_THAN: + case COMPARE_GREATER_THAN_EQUAL: return "compareTo"; case BITWISE_AND: 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 3b9eaa531b..7d92957b55 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -4335,6 +4335,11 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { if (isBoolIntrinsicOp(op)) { return boolean_TYPE; } + if (op == FIND_REGEX) { + // this case always succeeds the result is a Matcher + return Matcher_TYPE; + } + if (isArrayOp(op)) { // using getPNR() to ignore generics at this point // and a different binary expression not to pollute the AST @@ -4346,39 +4351,37 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { } return method != null ? inferComponentType(left, right) : null; } - if (op == FIND_REGEX) { - // this case always succeeds the result is a Matcher - return Matcher_TYPE; - } - // the left operand is determining the result of the operation - // for primitives and their wrapper we use a fixed table here + String operationName = getOperationName(op); + if (operationName == null) throw new GroovyBugError( + "Unknown result type for binary operator " + op); + // the left operand is determining the result of the operation + // for primitives and their wrapper we use a fixed table here: ClassNode mathResultType = getMathResultType(op, leftRedirect, rightRedirect, operationName); if (mathResultType != null) { return mathResultType; } - // GROOVY-9006: compare to null for types that overload equals if ("equals".equals(operationName) && (left == UNKNOWN_PARAMETER_TYPE || right == UNKNOWN_PARAMETER_TYPE)) { return boolean_TYPE; } - // GROOVY-5890: do not mix Class<Type> with Type if (leftExpression instanceof ClassExpression) { left = CLASS_Type.getPlainNodeReference(); } - MethodNode method = findMethodOrFail(expr, left, operationName, right); if (method != null) { storeTargetMethod(expr, method); typeCheckMethodsWithGenericsOrFail(left, new ClassNode[]{right}, method, expr); + if (isAssignment(op)) return left; - if (isCompareToBoolean(op)) return boolean_TYPE; - if (op == COMPARE_TO) return int_TYPE; - return inferReturnTypeGenerics(left, method, args(rightExpression)); + if (!"compareTo".equals(operationName)) + return inferReturnTypeGenerics(left, method, args(rightExpression)); } - //TODO: other cases + + if (isCompareToBoolean(op)) return boolean_TYPE; + if (op == COMPARE_TO) return int_TYPE; return null; } diff --git a/src/main/java/org/codehaus/groovy/transform/trait/Traits.java b/src/main/java/org/codehaus/groovy/transform/trait/Traits.java index 23dd99734e..7743e95688 100644 --- a/src/main/java/org/codehaus/groovy/transform/trait/Traits.java +++ b/src/main/java/org/codehaus/groovy/transform/trait/Traits.java @@ -261,17 +261,17 @@ public abstract class Traits { } /** - * Returns the name of a method without the super trait specific prefix. If the method name - * doesn't correspond to a super trait method call, the result will be null. - * @param origName the name of a method - * @return null if the name doesn't start with the super trait prefix, otherwise the name without the prefix + * Returns the trait and method names derived from super-trait name scheme + * or {@code null} if the method name doesn't correspond to a trait method. */ - public static String[] decomposeSuperCallName(String origName) { - if (origName.contains(SUPER_TRAIT_METHOD_PREFIX)) { - int endIndex = origName.indexOf(SUPER_TRAIT_METHOD_PREFIX); - String tName = origName.substring(0, endIndex).replace('_','.').replace("..","_"); - String fName = origName.substring(endIndex+SUPER_TRAIT_METHOD_PREFIX.length()); - return new String[]{tName, fName}; + public static String[] decomposeSuperCallName(final String methodName) { + if (methodName != null) { + int endIndex = methodName.indexOf(SUPER_TRAIT_METHOD_PREFIX); + if (endIndex != -1) { + String tName = methodName.substring(0, endIndex).replace('_', '.').replace("..", "_"); + String fName = methodName.substring(endIndex + SUPER_TRAIT_METHOD_PREFIX.length()); + return new String[]{tName, fName}; + } } return null; } diff --git a/src/spec/test/typing/TypeCheckingTest.groovy b/src/spec/test/typing/TypeCheckingTest.groovy index fc87413438..180d0b75a5 100644 --- a/src/spec/test/typing/TypeCheckingTest.groovy +++ b/src/spec/test/typing/TypeCheckingTest.groovy @@ -833,7 +833,7 @@ import static org.codehaus.groovy.ast.tools.WideningCategories.lowestUpperBound } } // end::cl_pt_failure[] - ''', 'No such property: age for class: java.lang.Object', 'Cannot find matching method' + ''', 'No such property: age for class: java.lang.Object' assertScript ''' class Person {
