diff --git a/build.gradle b/build.gradle index 4bc522d85f9..15271427d8a 100644 --- a/build.gradle +++ b/build.gradle @@ -202,9 +202,10 @@ dependencies { testImplementation project(':groovy-ant') testImplementation project(':groovy-xml') - testImplementation project(':groovy-dateutil') + testImplementation project(':groovy-json') testImplementation project(':groovy-test') testImplementation project(':groovy-macro') + testImplementation project(':groovy-dateutil') } ext.generatedDirectory = "${buildDir}/generated/sources" 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 67e1d99c7a1..0b3166b15bf 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -219,6 +219,7 @@ import static org.codehaus.groovy.syntax.Types.KEYWORD_IN; import static org.codehaus.groovy.syntax.Types.KEYWORD_INSTANCEOF; import static org.codehaus.groovy.syntax.Types.LEFT_SQUARE_BRACKET; +import static org.codehaus.groovy.syntax.Types.LOGICAL_OR; import static org.codehaus.groovy.syntax.Types.MINUS_MINUS; import static org.codehaus.groovy.syntax.Types.MOD; import static org.codehaus.groovy.syntax.Types.MOD_EQUAL; @@ -727,6 +728,9 @@ public void visitBinaryExpression(final BinaryExpression expression) { typeCheckingContext.pushEnclosingBinaryExpression(expression); try { int op = expression.getOperation().getType(); + if (op == LOGICAL_OR) { + typeCheckingContext.pushTemporaryTypeInfo(); + } Expression leftExpression = expression.getLeftExpression(); Expression rightExpression = expression.getRightExpression(); @@ -735,6 +739,7 @@ public void visitBinaryExpression(final BinaryExpression expression) { ClassNode lType = null; if (setterInfo != null) { if (ensureValidSetter(expression, leftExpression, rightExpression, setterInfo)) { + if (op == LOGICAL_OR) typeCheckingContext.popTemporaryTypeInfo(); return; } } else { @@ -780,6 +785,8 @@ public void visitBinaryExpression(final BinaryExpression expression) { elvisOperatorExpression.visit(this); resultType = getType(elvisOperatorExpression); storeType(leftExpression, resultType); + } else if (op == LOGICAL_OR) { + typeCheckingContext.popTemporaryTypeInfo(); } if (resultType == null) { diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy index 4c5b818d1b8..dc6f1b2aeae 100644 --- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy +++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy @@ -401,7 +401,7 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase { foo(it) } } - ''', 'Reference to method is ambiguous' + ''', 'Cannot find matching method' } void testShouldFailWithMultiplePossibleMethods2() { @@ -420,7 +420,26 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase { foo(argument) } } - ''', 'Reference to method is ambiguous' + ''', 'Cannot find matching method' + } + + // GROOVY-7971 + void testShouldNotFailWithMultiplePossibleMethods() { + assertScript ''' + import groovy.json.JsonOutput + + def test(value) { + def out = new StringBuilder() + def isString = value.class == String + if (isString || value instanceof Map) { + out.append(JsonOutput.toJson(value)) + } + return out.toString() + } + + def string = test('two') + assert string == '"two"' + ''' } void testInstanceOfOnExplicitParameter() {