Skip to content

Fix ChangeType UnsupportedOperationException on JS FunctionCall nodes#7239

Merged
knutwannheden merged 3 commits intomainfrom
fix-changetype-unsupportedoperationexception-on-js-nodes
Apr 2, 2026
Merged

Fix ChangeType UnsupportedOperationException on JS FunctionCall nodes#7239
knutwannheden merged 3 commits intomainfrom
fix-changetype-unsupportedoperationexception-on-js-nodes

Conversation

@knutwannheden
Copy link
Copy Markdown
Contributor

@knutwannheden knutwannheden commented Apr 2, 2026

Motivation

When running Java recipes (e.g., NoGuavaPredicateChangeType) against repositories containing JavaScript files, ChangeType.postVisit() throws UnsupportedOperationException on JS.FunctionCall nodes. This was discovered in flagship recipe run alerts on app.moderne.io — the "Java best practices" recipe run against Netflix+Spring org produced 46 per-file errors on metaflow/plugins/cards/ui/prism.js.

The root cause: ChangeType.postVisit() has explicit handling for J.MethodInvocation and J.NewClass (both MethodCall implementations), but JS.FunctionCall — also a MethodCall — falls through to the generic TypedTree branch, which calls withType(). All MethodCall implementations throw UnsupportedOperationException on withType() because the type is derived from the method type.

Additionally, J.ClassDeclaration.type (a JavaType.FullyQualified) was not being serialized over RPC, causing JavaScript class declarations to lose their type attribution when crossing the RPC boundary.

Summary

  • Add a MethodCall catch-all branch in ChangeType.postVisit() between the J.NewClass and TypedTree branches, using withMethodType() instead of withType()
  • Add J.ClassDeclaration.type to the RPC sender/receiver in all language implementations (Java, TypeScript, C#, Python)
  • Add ChangeTypeAdaptabilityTest in rewrite-javascript that verifies ChangeType can handle JS source containing FunctionCall nodes

Test plan

  • New ChangeTypeAdaptabilityTest.functionCallDoesNotThrow() — applies ChangeType("Foo", "Bar", false) to JavaScript containing a class with a method returning a function, verifying both the class rename and that JS.FunctionCall nodes don't cause exceptions
  • Existing ChangeTypeTest in rewrite-java-test passes
  • Existing ChangeTypeAdaptabilityTest in rewrite-groovy passes
  • Existing ChangeTypeTest in rewrite-kotlin passes

@github-project-automation github-project-automation bot moved this to In Progress in OpenRewrite Apr 2, 2026
@knutwannheden knutwannheden force-pushed the fix-changetype-unsupportedoperationexception-on-js-nodes branch from b5f46c2 to b7a680a Compare April 2, 2026 08:35
@github-project-automation github-project-automation bot moved this from In Progress to Ready to Review in OpenRewrite Apr 2, 2026
ChangeType.postVisit() falls through to the TypedTree branch for
JS.FunctionCall nodes, which throws UnsupportedOperationException
because withType() is not supported on MethodCall implementations.

Add a MethodCall catch-all branch before the TypedTree fallback that
uses withMethodType() instead, handling JS.FunctionCall and any other
future MethodCall implementations not explicitly handled.
@knutwannheden knutwannheden force-pushed the fix-changetype-unsupportedoperationexception-on-js-nodes branch from b7a680a to 0bceb5c Compare April 2, 2026 08:51
This test exercises the JS RPC parser and belongs with the other
integration tests that are not run in CI.
@knutwannheden knutwannheden merged commit cd4178c into main Apr 2, 2026
1 of 2 checks passed
@knutwannheden knutwannheden deleted the fix-changetype-unsupportedoperationexception-on-js-nodes branch April 2, 2026 14:14
@github-project-automation github-project-automation bot moved this from Ready to Review to Done in OpenRewrite Apr 2, 2026
@knutwannheden knutwannheden changed the title Fix ChangeType UnsupportedOperationException on JS FunctionCall nodes Fix ChangeType UnsupportedOperationException on JS FunctionCall nodes Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants