From 375df5cb6babefa4e3f5cbe7b0d4e21cc0d6c5df Mon Sep 17 00:00:00 2001 From: Jonathan Schneider Date: Thu, 17 Jul 2025 14:33:57 -0400 Subject: [PATCH] Fix NPE in IteratorNext recipe when iterator() has no explicit receiver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recipe failed with a NullPointerException when encountering code like `iterator().next()` where the iterator() method is called without an explicit receiver (using implicit `this`). This fix adds a null check for `iteratorSelect` before attempting to check its type. Added test case to verify the recipe correctly handles implicit receiver cases without throwing NPE. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../java/migrate/util/IteratorNext.java | 2 +- .../java/migrate/util/IteratorNextTest.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/openrewrite/java/migrate/util/IteratorNext.java b/src/main/java/org/openrewrite/java/migrate/util/IteratorNext.java index 454a9dcd04..632b3156f8 100644 --- a/src/main/java/org/openrewrite/java/migrate/util/IteratorNext.java +++ b/src/main/java/org/openrewrite/java/migrate/util/IteratorNext.java @@ -59,7 +59,7 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu if (NEXT_MATCHER.matches(nextInvocation) && ITERATOR_MATCHER.matches(nextInvocation.getSelect())) { J.MethodInvocation iteratorInvocation = (J.MethodInvocation) nextInvocation.getSelect(); Expression iteratorSelect = iteratorInvocation.getSelect(); - if (TypeUtils.isAssignableTo("java.util.SequencedCollection", iteratorSelect.getType())) { + if (iteratorSelect != null && TypeUtils.isAssignableTo("java.util.SequencedCollection", iteratorSelect.getType())) { JavaType.Method getFirst = iteratorInvocation.getMethodType().withName("getFirst"); return iteratorInvocation .withName(iteratorInvocation.getName().withSimpleName("getFirst").withType(getFirst)) diff --git a/src/test/java/org/openrewrite/java/migrate/util/IteratorNextTest.java b/src/test/java/org/openrewrite/java/migrate/util/IteratorNextTest.java index 50e53c16de..a987d22352 100644 --- a/src/test/java/org/openrewrite/java/migrate/util/IteratorNextTest.java +++ b/src/test/java/org/openrewrite/java/migrate/util/IteratorNextTest.java @@ -140,4 +140,22 @@ void bar(List collection) { ) ); } + + @Test + void implicitThisIteratorNextUnchanged() { + rewriteRun( + //language=java + java( + """ + import java.util.*; + + class Foo extends ArrayList { + void bar() { + String first = iterator().next(); + } + } + """ + ) + ); + } }