fix: Java extractor — camelCase accessor chains and TestResources fixtures - #4
Merged
Merged
Conversation
…xtures
The Java code-example extractor had two bugs that produced incorrect manifests
for the phenoml-java-sdk:
- `sdkMethodChain` used lowercased directory names (e.g. `fhirprovider`,
`lang2fhir`, `mcpserver`), but the Java SDK accessors are camelCase
(`fhirProvider()`, `lang2Fhir()`, `mcpServer()`). Consumers reconstructing
Java calls from the chain produced non-compiling code. Build an accessor
map by scanning main `*Client.java` files for `public XxxClient method()`
patterns, then remap each directory segment.
- Wire tests whose responses are loaded via
`TestResources.loadResource("/wire-tests/Foo.json")` emitted null response
bodies because `javaExtractSetBody` / `javaExtractConcatenatedString` only
recognised inline string literals. Both now resolve `loadResource(...)`
calls to the fixture file under `src/test/resources/`.
Adds a new `java-accessor` fixture exercising both fixes end-to-end plus unit
tests for the new helpers.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Dedupe the `TestResources.loadResource("/path")` matcher into a single
`javaTryLoadResource` helper used by both `javaExtractSetBody` and
`javaExtractConcatenatedString`; eliminates two near-identical regex
patterns and `if (rootDir)` guard blocks.
- Replace the `existsSync` + `readFileSync` TOCTOU pattern with a single
`readFileSync` in try/catch.
- Drop the redundant `existsSync` guard in `javaBuildAccessorMap` —
`findFiles` already handles a missing directory.
- Unexport `javaLoadTestResource`; drop its two direct unit tests
(already covered end-to-end via the extractor tests).
- Strip narrative ("before this fix", "Backwards-compatible") and
regex-paraphrasing comments throughout the added code and tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`javaBuildAccessorMap` previously indexed candidate `*Client.java` files by basename, which collapsed two distinct files with the same class name (e.g. a top-level `ToolsClient.java` and a nested `tools/mcpserver/tools/ToolsClient.java`) into a single map entry. The losing branch's directory was left unmapped, so its `sdkMethodChain` fell back to the lowercased directory name instead of the real camelCase accessor. Resolve each `public XxxClient methodName()` to a file path using the accessor file's `package` declaration plus its `import` statements. Each branch resolves to its own file regardless of class-name collisions. Adds a duplicate-basename case (`tools/mcpserver/tools/ToolsClient.java`) to the java-accessor fixture and asserts that both `tools/` directories are mapped independently. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
extract-code-examplesJava parser sosdkMethodChainuses real camelCase accessors (fhirProvider,lang2Fhir,mcpServer) instead of lowercased directory names that don't compile against the Java SDK.TestResources.loadResource("/wire-tests/*.json")calls in wire tests so response bodies are populated from fixture files instead of emitted asnull.javaBuildAccessorMapscans main*Client.javafiles forpublic XxxClient method()patterns; newjavaTryLoadResourcereads classpath fixtures fromsrc/test/resources/.java-accessorfixture (FhirProvider + nestedtools/mcpServer) plus unit and end-to-end tests covering both fixes.Test plan
bun test extract-code-examples— 51 tests pass🤖 Generated with Claude Code
Note
Medium Risk
Moderate risk because it changes Java endpoint chain derivation and wire-test body extraction logic, which could alter generated manifests for Java SDKs; changes are well-covered by new unit and fixture-based tests.
Overview
Fixes the Java
extract-code-examplesparser so generatedsdkMethodChainuses the actual camelCase accessor methods exposed by Java SDK clients (via a newjavaBuildAccessorMapused byjavaDeriveMethodChain/javaExtractEndpoints), rather than lowercased resource directory names.Enhances Java wire-test extraction to resolve
TestResources.loadResource("/...")calls by loading JSON fixtures fromsrc/test/resources, improving request/response body capture.Adds a new
java-accessorSDK fixture plus targeted unit and end-to-end tests covering accessor mapping (including duplicate*Clientbasenames) and resource-backed bodies.Reviewed by Cursor Bugbot for commit c9c4785. Bugbot is set up for automated code reviews on this repo. Configure here.