diff --git a/src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java b/src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java index 673de0bf105..f7d24af4799 100644 --- a/src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java +++ b/src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java @@ -598,19 +598,22 @@ private void tryRecoverTypeArguments(CtTypeReference type) { } AllocationExpression alloc = (AllocationExpression) stack.peek().node; - if (alloc.expectedType() == null || !(alloc.expectedType() instanceof ParameterizedTypeBinding)) { - // the expected type is not available/parameterized if the constructor call occurred in e.g. an unresolved - // method, or in a method that did not expect a parameterized argument - type.addActualTypeArgument(jdtTreeBuilder.getFactory().Type().OMITTED_TYPE_ARG_TYPE.clone()); - } else { + if (alloc.expectedType() instanceof ParameterizedTypeBinding) { ParameterizedTypeBinding expectedType = (ParameterizedTypeBinding) alloc.expectedType(); - // type arguments can be recovered from the expected type - for (TypeBinding binding : expectedType.typeArguments()) { - CtTypeReference typeArgRef = getTypeReference(binding); - typeArgRef.setImplicit(true); - type.addActualTypeArgument(typeArgRef); + if (expectedType.typeArguments() != null) { + // type arguments can be recovered from the expected type + for (TypeBinding binding : expectedType.typeArguments()) { + CtTypeReference typeArgRef = getTypeReference(binding); + typeArgRef.setImplicit(true); + type.addActualTypeArgument(typeArgRef); + } } + return; } + + // the expected type is not available/parameterized if the constructor call occurred in e.g. an unresolved + // method, or in a method that did not expect a parameterized argument + type.addActualTypeArgument(jdtTreeBuilder.getFactory().Type().OMITTED_TYPE_ARG_TYPE.clone()); } /** diff --git a/src/test/java/spoon/test/methodreference/MethodReferenceTest.java b/src/test/java/spoon/test/methodreference/MethodReferenceTest.java index 23d1c8320e3..3c155efc6a9 100644 --- a/src/test/java/spoon/test/methodreference/MethodReferenceTest.java +++ b/src/test/java/spoon/test/methodreference/MethodReferenceTest.java @@ -174,6 +174,11 @@ public void testCompileMethodReferenceGeneratedBySpoon() { canBeBuilt(new File("./target/spooned/spoon/test/methodreference/testclasses/"), 8); } + @Test + public void testTryRecoverTypeArgumentsHandlesNullTypeArguments() { + canBeBuilt("./src/test/resources/ReferenceBuilder-null-pointer/", 8); + } + @Test public void testNoClasspathExecutableReferenceExpression() { final Launcher launcher = new Launcher(); diff --git a/src/test/resources/ReferenceBuilder-null-pointer/Foo.java b/src/test/resources/ReferenceBuilder-null-pointer/Foo.java new file mode 100644 index 00000000000..9c008c1edd7 --- /dev/null +++ b/src/test/resources/ReferenceBuilder-null-pointer/Foo.java @@ -0,0 +1,10 @@ +import java.util.ArrayList; +import java.util.Collection; + +public class Foo { + public void accept(Collection y) {} + + public void doSomething(Collection x) { + accept(new ArrayList<>(x)); + } +}