Skip to content

Improve transformation robustness, filtering, and structural operations#48

Merged
Vladislav Artiukhov (Vladislav0Art) merged 72 commits into
mainfrom
vartiukhov/feature/codecocoon-modifications
Jun 2, 2026
Merged

Improve transformation robustness, filtering, and structural operations#48
Vladislav Artiukhov (Vladislav0Art) merged 72 commits into
mainfrom
vartiukhov/feature/codecocoon-modifications

Conversation

@Vladislav0Art

@Vladislav0Art Vladislav Artiukhov (Vladislav0Art) commented May 22, 2026

Copy link
Copy Markdown
Collaborator

Description

Introduced changes:

  1. ❗️Execution config now accepts a full filepath to a memory JSON file instead of a directory path. It makes it more suitable for automated evaluation (it is easier to pass a file path to a JSON file than to find a file in a given directory whose name depends on the given project's name).
  2. ❗️HeadlessModeStarter.kt sets several style configurations that blocks some of the unwanted import modifications that otherwise occur automatically on project close (it does NOT fix CodeCocoon automatically removes unused imports, which introduced file modifications unintended by the applied transformation #50 though).
  3. ‼️ Renaming transformations (class/method/variable) are parameterizable with either whitelist or blacklist annotation sets: 1) when a whitelist is passed, the transformation applies to code that either contains no annotations OR only those in the whitelist; 2) when a blacklist is passed, the transformation applies to code that either contains no annotations or the code that has ANY annotation excluding those in the blacklist.
  4. ❗️Introduced ReorderClassMethodsTransformation.kt‎: it reorders methods in a class in a reversed alphabetic order (Z->A).
  5. Added withSmartReadAction: similar to withReadAction helper that awaits the smart mode execution context (I had some scenarios where it mattered in Multi-SWE-Bench) + used it in the transformations.
  6. Misc AI-generated modifications that patch renaming transformations to work correctly on different scenarios where the transformations did not rename the code correctly (mainly, these scenarios were found during eval on Multi-SWE-Bench). ❗️RenameMethodTransformation.kt‎ received the most modifications as it turned out to be the most buggy one and did not rename a lot of call sites and definitions.
  7. TransformationService.kt counts 1) succeeded, 2) failed, and 3) skipped transformations to show it in the output (useful logging for scaled eval).
  8. Updates README that reflects the transformations' config parameters.
  9. Minor modifications to file-moving transformation.

Andrei Drăgoi (dragoi75) and others added 30 commits April 16, 2026 23:00
…unused import optimization)

Left optimizations:
1. Import of a class from the same package.
2. Unused import.

Both imports above are removed when references are updated in a file that uses a renamed class/method.
…leFilters` method in `RenameVariableTransformation`
…and CLI support via `RewriteProblemStatementStarter`
… and integrate with CLI starters

- Introduced `BenchmarkInstanceIO` for JSON parsing and transformation of benchmark records.
- Updated `RewriteProblemStatementStarter` and `TransformTextsStarter` to process `{title, body}` pairs and `resolved_issues`.
- Added `TextBlock` data class to support coherent updates across textual fields.
- Enhanced Gradle tasks `rewriteProblemStatement` and `transformMetamorphicTexts` with improved input/output handling.
…n-deterministic behavior during project close and renaming operations
… prevent inconsistent state during subsequent operations
… inconsistent behavior across transformations
Changes:
- Skip override check for static methods to avoid false positives caused by unrelated name matches.
- Ensure instance methods are genuine overrides by verifying super-methods are within the declared inheritance chain.
…leTransformation` to avoid additional modifications in base+test_patch run
…ansformation` with exponential backoff and robustness enhancements
…by explicitly attaching transitive overriders to the rename processor

`RenameProcessor`'s implicit override expansion via
`RenameJavaMethodProcessor.prepareRenaming` + `OverridingMethodsSearch`
silently dropped sibling overloads' overriders when multiple same-name
overloads were renamed to the same target name through a single
processor — only the seed overload's overrider got renamed, the others
kept the old name. The post-rename safety net `verifyAndPatchMissedCallSites`
only inspected `PsiMethodCallExpression` nodes, never `PsiMethod`
declarations, so missed override definitions were invisible to it.

Reproducer: an abstract base `A` with `write(JsonValue)` + `write(String)`
and `B extends A` overriding both. After renaming `A.write` to
`A.writeTo`, `B.write(JsonValue)` followed but `B.write(String)` was
left dangling with the old name.

In `tryRenameMethodFamily`, after the existing overload-sibling
`addElement` loop, enumerate transitive overriders via
`OverridingMethodsSearch.search(method, checkDeep = true)` for every
family method and attach each (skipping family members already added
and overriders in libraries) as a first-class rename target. Adding
them explicitly forces the same rename path that already works for the
seed; when implicit expansion would have caught them anyway, it is a
no-op via `myAllRenames` dedup, so the change is backward compatible.
…sformation` with exponential backoff

Mirror the robust LLM call path already used in
`RenameVariableTransformation`: each file now issues a single batched
LLM request listing every overload family (chunked at LLM_BATCH_SIZE=20
to keep prompt size manageable since each entry embeds a method body),
with up to LLM_MAX_ATTEMPTS=3 retries per batch and exponential backoff
(4s → 8s, capped at 12s) on transient failures.
`ProcessCanceledException` is rethrown per IntelliJ contract; permanent
failures return an empty list so affected families are skipped (no
rename, no memory write) without failing the whole transformation, and
other batches and other files keep progressing.

Wire format: replace `MethodNameSuggestions(suggestions)` with
`MethodFamilyRenaming(familyKey, suggestions)` +
`MethodRenameSuggestions(renamings)`. Each overload family carries a
precomputed `familyKey` of the form
`<classFqn>#<methodName>[<static|instance>]` so the model can echo it
back per entry — the `[static]/[instance]` tag prevents same-name
static/instance siblings in the same class from colliding in the batch.
`generateRenamesForFamilies` now matches results back via
`familyKey == family.familyKey` and pipes them through the unchanged
`buildSuggestionList` helper.

`extractRenamesFromMemoryForFamilies`, `tryRenameMethodFamily`, the
overrider-attachment / verify-and-patch / rich-logging code, and the
memory key format are untouched.
…oting discovery reads to smart-mode

`RenameProcessor.run()` + `commitAllDocuments()` + `saveAllDocuments()`
drops the IDE back into dumb mode while the stub index is recomputed,
so the next file's transformation can land mid-reindex. Any read action
that resolves a super-class hierarchy then hits the stub index and
throws. Reproduced on Multi-SWE-Bench:

- `RenameClassTransformation` — `psiClass.allFields` walks `MemberCache`
  → `getSupers()` → `findSpecialSuperClass()` → `JavaFullClassNameIndex`.
- `RenameMethodTransformation` — `method.findSuperMethods()` builds a
  hierarchical signature → `getSuperTypes()` →
  `findClass(java.lang.Object)`.

Per the `IndexNotReadyException` Javadoc, promote the topmost read
action to smart mode. Add a `withSmartReadAction(project) { ... }`
companion helper on `IntelliJAwareTransformation` (mirrors
`withReadAction` but uses suspending `smartReadAction(project)`, so the
block waits for index readiness before running) and use it at the
discovery sites:

- `RenameClassTransformation.apply` — the `findAllValidClasses(...)`
  wrap (also covers the per-class `ReferencesSearch.search(cls)` and
  `fileIndex.isInTestSourceContent(...)` calls inside).
- `RenameClassTransformation.generateNewClassNames` — the PSI-context
  extraction (covers `psiClass.allFields` — the exact line that threw).
- `RenameMethodTransformation.apply` — the
  `findAllValidMethodFamilies(...)` wrap (covers `findSuperMethods()`,
  `psiClass.supers`, and `ReferencesSearch.search(method)` inside the
  override-filter walk).

`tryRenameClassAndUsages` and `tryRenameMethodFamily` keep using plain
`withReadAction { ... }` — they run after the discovery walk (the
natural index-settling point) and adding `runBlocking` inside their
existing `invokeAndWait` envelopes risks deadlocks. Cancellation
contract preserved: `smartReadAction` honours `ProcessCanceledException`
propagation.
@Vladislav0Art

Copy link
Copy Markdown
Collaborator Author

Copilot given the changes in this PR create a description and a title for it

Copilot AI commented May 22, 2026

Copy link
Copy Markdown

Copilot given the changes in this PR create a description and a title for it

Proposed PR title:
Improve transformation robustness, filtering, and structural operations

Proposed PR description:
This PR strengthens CodeCocoon’s transformation pipeline by improving reliability and determinism in rename and move transformations, adding annotation-based filtering controls (whitelist/blacklist/default merge behavior), introducing class method reordering, and improving LLM suggestion batching/retry behavior. It also removes multi-SWE-bench/text-specific components, simplifies related internals, and updates configuration/docs to reflect the new behavior.

Reference commit: 8c04bea

@github-actions

Copy link
Copy Markdown

Qodana Community for JVM

3 new problems were found

Inspection name Severity Problems
Unresolved reference in KDoc 🔶 Warning 2
Class member can have 'private' visibility ◽️ Notice 1

💡 Qodana analysis was run in the pull request mode: only the changed files were checked

View the detailed Qodana report

To be able to view the detailed Qodana report, you can either:

To get *.log files or any other Qodana artifacts, run the action with upload-result option set to true,
so that the action will upload the files as the job artifacts:

      - name: 'Qodana Scan'
        uses: JetBrains/qodana-action@v2025.1.1
        with:
          upload-result: true
Contact Qodana team

Contact us at qodana-support@jetbrains.com

@Vladislav0Art Vladislav Artiukhov (Vladislav0Art) changed the title [tbd] Modifications Improve transformation robustness, filtering, and structural operations May 22, 2026
@Vladislav0Art Vladislav Artiukhov (Vladislav0Art) marked this pull request as ready for review May 22, 2026 13:17

@dragoi75 Andrei Drăgoi (dragoi75) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

In interest of both our time, I did not add any nitpicks. But thank you for all the changes!
You can merge

Should we also close #47 ?

@Vladislav0Art Vladislav Artiukhov (Vladislav0Art) merged commit fa304ae into main Jun 2, 2026
7 checks passed
@Vladislav0Art

Copy link
Copy Markdown
Collaborator Author

LGTM 👍

In interest of both our time, I did not add any nitpicks. But thank you for all the changes! You can merge

Should we also close #47 ?

Thanks for the review! I closed #47 in favor of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CodeCocoon automatically removes unused imports, which introduced file modifications unintended by the applied transformation

3 participants