Method-Rename: Virtual vs Non-Virtual Processor fehlt #29

Open
opened 2026-03-08 09:25:50 +00:00 by automation · 1 comment
Collaborator

Problem

jdt_rename_element auf Interface-Methoden mit Generics aktualisiert Implementierungen in anderen Modulen nicht.

Betrifft nur: Virtuelle Methoden (Interface/Override) mit Generics-Typ-Parametern.
Funktioniert: Felder, Klassen, nicht-virtuelle Methoden — auch cross-project.

Reproduktion (Test I4, v0.2.18)

jdt_rename_element(elementName="org.fixture.api.Processor#process", newName="execute", elementType="METHOD")

Ergebnis: STATUS=SUCCESS, aber nur 3 Dateien geändert:

  1. Processor.java (fixture-api) — Interface-Deklaration
  2. AppService.java (fixture-app) — Caller
  3. ExternalService.java (fixture-external) — Caller

Fehlend:

  • SimpleProcessor.java (fixture-core) — behält process() statt execute()
  • BatchProcessor.java (fixture-core) — behält process() statt execute()
  • BaseProcessor.java (fixture-core) — behält process() statt execute()

→ 4 Compile-Fehler

Root Cause: JDT Generics-Binding-Resolution im Headless-Modus

RenameVirtualMethodProcessor (Processor-basierter Weg)

  • Wird korrekt gewählt (isVirtual=true, RenameVirtualMethodProcessor)
  • checkFinalConditions läuft ohne Fehler durch
  • createChange produziert Changes — aber nur für Caller, nicht für Implementierungen
  • Intern nutzt RippleMethodFinder2 den MethodOverrideTester mit Binding-Vergleichen
  • Processor<T>.process(T) hat Signatur (QT;) — die Implementierung process(String) hat (QString;)
  • Der MethodOverrideTester braucht aufgelöste Bindings für die Erasure-Zuordnung, die im Headless-Mode fehlen

SearchEngine (AST-basierter Weg)

  • ALL_OCCURRENCES findet ebenfalls nur Interface-Deklaration + Caller
  • Override-Methoden in Subtypes werden nicht als Occurrences erkannt (gleiches Generics-Problem)

TypeHierarchy (funktioniert!)

  • IType.newTypeHierarchy() findet alle Subtypes korrekt
  • IType.getMethods() listet die Methoden korrekt
  • Aber: Nur die Deklarationen können so gepatcht werden, nicht die zugehörigen Call-Sites und Self-Calls

Versuchte Fix-Ansätze (alle gescheitert)

  1. Post-Check mit TypeHierarchy: Findet fehlende Implementierungen, patcht aber nur Deklarationen — Call-Sites und Self-Calls bleiben unberührt
  2. AST-Fallback mit ALL_OCCURRENCES: SearchEngine hat dasselbe Generics-Problem wie der Processor
  3. AST-Fallback mit REFERENCES: Findet nur Aufrufe, keine Override-Deklarationen

Offene Frage

Ob das Problem auch bei virtuellen Methoden ohne Generics auftritt (z.B. void doStuff(String) in Interface und Implementierung). Falls nicht, ist es rein ein Generics-Binding-Problem.

Status

  • Diagnostic Logging hinzugefügt (commit 65daec8)
  • Fix-Versuche revertiert — kein sauberer Workaround gefunden
  • Vermutlich ein Bug in Eclipse JDT im Headless-Modus (upstream melden?)

Kontext

  • Ursprünglich identifiziert bei der Analyse von #26 durch Agent jdt-vogel
  • Bestätigt im Test-Report v0.2.18 (Test I4)
  • Analyse-Details aus 3 Test-Runs mit erweitertem Logging
## Problem `jdt_rename_element` auf Interface-Methoden mit Generics aktualisiert Implementierungen in anderen Modulen nicht. **Betrifft nur:** Virtuelle Methoden (Interface/Override) mit Generics-Typ-Parametern. **Funktioniert:** Felder, Klassen, nicht-virtuelle Methoden — auch cross-project. ## Reproduktion (Test I4, v0.2.18) ``` jdt_rename_element(elementName="org.fixture.api.Processor#process", newName="execute", elementType="METHOD") ``` **Ergebnis:** STATUS=SUCCESS, aber nur 3 Dateien geändert: 1. `Processor.java` (fixture-api) — Interface-Deklaration ✅ 2. `AppService.java` (fixture-app) — Caller ✅ 3. `ExternalService.java` (fixture-external) — Caller ✅ **Fehlend:** - `SimpleProcessor.java` (fixture-core) — behält `process()` statt `execute()` ❌ - `BatchProcessor.java` (fixture-core) — behält `process()` statt `execute()` ❌ - `BaseProcessor.java` (fixture-core) — behält `process()` statt `execute()` ❌ → 4 Compile-Fehler ## Root Cause: JDT Generics-Binding-Resolution im Headless-Modus ### RenameVirtualMethodProcessor (Processor-basierter Weg) - Wird korrekt gewählt (`isVirtual=true`, `RenameVirtualMethodProcessor`) - `checkFinalConditions` läuft ohne Fehler durch - `createChange` produziert Changes — aber nur für Caller, nicht für Implementierungen - Intern nutzt `RippleMethodFinder2` den `MethodOverrideTester` mit Binding-Vergleichen - `Processor<T>.process(T)` hat Signatur `(QT;)` — die Implementierung `process(String)` hat `(QString;)` - Der `MethodOverrideTester` braucht aufgelöste Bindings für die Erasure-Zuordnung, die im Headless-Mode fehlen ### SearchEngine (AST-basierter Weg) - `ALL_OCCURRENCES` findet ebenfalls nur Interface-Deklaration + Caller - Override-Methoden in Subtypes werden **nicht** als Occurrences erkannt (gleiches Generics-Problem) ### TypeHierarchy (funktioniert!) - `IType.newTypeHierarchy()` findet alle Subtypes korrekt - `IType.getMethods()` listet die Methoden korrekt - **Aber:** Nur die Deklarationen können so gepatcht werden, nicht die zugehörigen Call-Sites und Self-Calls ## Versuchte Fix-Ansätze (alle gescheitert) 1. **Post-Check mit TypeHierarchy**: Findet fehlende Implementierungen, patcht aber nur Deklarationen — Call-Sites und Self-Calls bleiben unberührt 2. **AST-Fallback mit ALL_OCCURRENCES**: SearchEngine hat dasselbe Generics-Problem wie der Processor 3. **AST-Fallback mit REFERENCES**: Findet nur Aufrufe, keine Override-Deklarationen ## Offene Frage Ob das Problem auch bei virtuellen Methoden **ohne Generics** auftritt (z.B. `void doStuff(String)` in Interface und Implementierung). Falls nicht, ist es rein ein Generics-Binding-Problem. ## Status - Diagnostic Logging hinzugefügt (commit 65daec8) - Fix-Versuche revertiert — kein sauberer Workaround gefunden - Vermutlich ein Bug in Eclipse JDT im Headless-Modus (upstream melden?) ## Kontext - Ursprünglich identifiziert bei der Analyse von #26 durch Agent jdt-vogel - Bestätigt im Test-Report v0.2.18 (Test I4) - Analyse-Details aus 3 Test-Runs mit erweitertem Logging
Author
Collaborator

This is already implemented in RefactoringTools.java (lines 1577-1611):

  • isVirtualMethod(method) delegates to MethodChecks.isVirtual(method) (line 1607)
  • Virtual methods → RenameVirtualMethodProcessor (line 1579)
  • Non-virtual methods → RenameNonVirtualMethodProcessor (line 1583)

This was part of the PR #40 (AST-based rename fallback) merge. Can be closed.

This is already implemented in `RefactoringTools.java` (lines 1577-1611): - `isVirtualMethod(method)` delegates to `MethodChecks.isVirtual(method)` (line 1607) - Virtual methods → `RenameVirtualMethodProcessor` (line 1579) - Non-virtual methods → `RenameNonVirtualMethodProcessor` (line 1583) This was part of the PR #40 (AST-based rename fallback) merge. Can be closed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ai-tools/jdt-mcp-server#29
No description provided.