This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY-8965 in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 28a2dc2d5020aefe3f0a9e9e827a900d9a28dbcf Author: Eric Milles <[email protected]> AuthorDate: Thu Jul 7 15:39:41 2022 -0500 GROOVY-8965, GROOVY-10180, GROOVY-10668: STC: --- .../transform/stc/StaticTypeCheckingVisitor.java | 53 +++++++++------------- .../transform/stc/TypeInferenceSTCTest.groovy | 4 +- .../groovy/parser/antlr4/util/AstDumper.groovy | 20 ++++---- .../asm/sc/TypeInferenceStaticCompileTest.groovy | 15 ------ 4 files changed, 32 insertions(+), 60 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 ae0acf3d27..c1db1ac0c5 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -3752,7 +3752,8 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { } /** - * Given an object expression (a receiver expression), generate the list of potential receiver types. + * Given an object expression (a message receiver expression), generate list + * of possible types. * * @param objectExpression the receiver expression * @return the list of types the receiver may be @@ -3762,23 +3763,20 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { List<Receiver<String>> owners = new ArrayList<>(); if (typeCheckingContext.delegationMetadata != null && objectExpression instanceof VariableExpression - && ((VariableExpression) objectExpression).getName().equals("owner") + && ((Variable) objectExpression).getName().equals("owner") && /*isNested:*/typeCheckingContext.delegationMetadata.getParent() != null) { List<Receiver<String>> enclosingClass = Collections.singletonList( Receiver.make(typeCheckingContext.getEnclosingClassNode())); addReceivers(owners, enclosingClass, typeCheckingContext.delegationMetadata.getParent(), "owner."); } else { - if (!typeCheckingContext.temporaryIfBranchTypeInformation.isEmpty()) { - List<ClassNode> potentialReceiverType = getTemporaryTypesForExpression(objectExpression); - if (potentialReceiverType != null && !potentialReceiverType.isEmpty()) { - for (ClassNode node : potentialReceiverType) { - owners.add(Receiver.make(node)); - } - } + List<ClassNode> temporaryTypes = getTemporaryTypesForExpression(objectExpression); + int temporaryTypesCount = (temporaryTypes != null ? temporaryTypes.size() : 0); + if (temporaryTypesCount > 0) { // GROOVY-8965, GROOVY-10180, GROOVY-10668 + owners.add(Receiver.make(lowestUpperBound(temporaryTypes))); } if (typeCheckingContext.lastImplicitItType != null && objectExpression instanceof VariableExpression - && ((VariableExpression) objectExpression).getName().equals("it")) { + && ((Variable) objectExpression).getName().equals("it")) { owners.add(Receiver.make(typeCheckingContext.lastImplicitItType)); } if (isClassClassNodeWrappingConcreteType(receiver)) { @@ -3798,6 +3796,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { } } } + if (temporaryTypesCount > 1 && !(objectExpression instanceof VariableExpression)) { + owners.add(Receiver.make(new UnionTypeClassNode(temporaryTypes.toArray(ClassNode.EMPTY_ARRAY)))); + } } return owners; } @@ -4702,37 +4703,25 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { return null; } - private List<MethodNode> disambiguateMethods(List<MethodNode> methods, final ClassNode receiver, final ClassNode[] argTypes, final Expression call) { - if (methods.size() > 1 && receiver != null && argTypes != null) { + private List<MethodNode> disambiguateMethods(List<MethodNode> methods, final ClassNode receiver, final ClassNode[] arguments, final Expression call) { + if (methods.size() > 1 && receiver != null && arguments != null) { List<MethodNode> filteredWithGenerics = new LinkedList<>(); - for (MethodNode methodNode : methods) { - if (typeCheckMethodsWithGenerics(receiver, argTypes, methodNode)) { - if ((methodNode.getModifiers() & Opcodes.ACC_BRIDGE) == 0) { - filteredWithGenerics.add(methodNode); - } + for (MethodNode method : methods) { + if (typeCheckMethodsWithGenerics(receiver, arguments, method) + && (method.getModifiers() & Opcodes.ACC_BRIDGE) == 0) { + filteredWithGenerics.add(method); } } if (filteredWithGenerics.size() == 1) { return filteredWithGenerics; } + methods = extension.handleAmbiguousMethods(methods, call); } - if (methods.size() > 1) { - if (call instanceof MethodCall) { - List<MethodNode> methodNodeList = new LinkedList<>(); - - String methodName = ((MethodCall) call).getMethodAsString(); - - for (MethodNode methodNode : methods) { - if (!methodNode.getName().equals(methodName)) { - continue; - } - methodNodeList.add(methodNode); - } - - methods = methodNodeList; - } + if (methods.size() > 1 && call instanceof MethodCall) { + String methodName = ((MethodCall) call).getMethodAsString(); + methods = methods.stream().filter(m -> m.getName().equals(methodName)).collect(Collectors.toList()); } return methods; diff --git a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy index 93d67cd829..29757355d4 100644 --- a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy +++ b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy @@ -296,6 +296,7 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase { ''' } + @NotYetImplemented void testMultipleInstanceOf1() { assertScript ''' class A { @@ -356,6 +357,7 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase { } } + @NotYetImplemented void testMultipleInstanceOf5() { assertScript ''' void test(thing) { @@ -365,7 +367,7 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase { thing.addElement(2) // 'addElement' only in Stack } if (thing instanceof Deque || thing instanceof Stack) { - assert thing.peek() in 1..2 // 'peek' in ArrayDeque and Stack but not LUB + assert thing.peek() in 1..2 // 'peek' in Deque and Stack but not LUB } } test(new Stack()) diff --git a/src/test/org/apache/groovy/parser/antlr4/util/AstDumper.groovy b/src/test/org/apache/groovy/parser/antlr4/util/AstDumper.groovy index 165f2f26eb..f67e01e6c6 100644 --- a/src/test/org/apache/groovy/parser/antlr4/util/AstDumper.groovy +++ b/src/test/org/apache/groovy/parser/antlr4/util/AstDumper.groovy @@ -641,8 +641,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati @Override void visitMethodCallExpression(MethodCallExpression expression) { - - Expression objectExp = expression.getObjectExpression() + Expression objectExp = expression.objectExpression if (objectExp instanceof VariableExpression) { visitVariableExpression(objectExp, false) } else { @@ -655,25 +654,23 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati print '?' } print '.' - Expression method = expression.getMethod() + Expression method = expression.method if (method instanceof ConstantExpression) { visitConstantExpression(method, true) } else { method.visit(this) } - expression.getArguments().visit(this) + expression.arguments.visit(this) } @Override void visitStaticMethodCallExpression(StaticMethodCallExpression expression) { print expression?.ownerType?.name + '.' + expression?.method - if (expression?.arguments instanceof VariableExpression || expression?.arguments instanceof MethodCallExpression) { - print '(' - expression?.arguments?.visit this - print ')' - } else { - expression?.arguments?.visit this - } + boolean parens = expression?.arguments instanceof VariableExpression + || expression?.arguments instanceof MethodCallExpression + if (parens) print '(' + expression?.arguments?.visit this + if (parens) print ')' } @Override @@ -1132,5 +1129,4 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati } return true } - } diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/TypeInferenceStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/TypeInferenceStaticCompileTest.groovy index b1ff1521c5..d35e1b50d7 100644 --- a/src/test/org/codehaus/groovy/classgen/asm/sc/TypeInferenceStaticCompileTest.groovy +++ b/src/test/org/codehaus/groovy/classgen/asm/sc/TypeInferenceStaticCompileTest.groovy @@ -31,11 +31,6 @@ class TypeInferenceStaticCompileTest extends TypeInferenceSTCTest implements Sta super.testInstanceOf9() } - @Override @NotYetImplemented - void testMultipleInstanceOf1() { - super.testMultipleInstanceOf1() - } - @Override @NotYetImplemented void testMultipleInstanceOf2() { super.testMultipleInstanceOf2() @@ -45,14 +40,4 @@ class TypeInferenceStaticCompileTest extends TypeInferenceSTCTest implements Sta void testMultipleInstanceOf3() { super.testMultipleInstanceOf3() } - - @Override @NotYetImplemented - void testMultipleInstanceOf4() { - super.testMultipleInstanceOf4() - } - - @Override @NotYetImplemented - void testMultipleInstanceOf5() { - super.testMultipleInstanceOf5() - } }
