redhat-developer / redhat-developer/vscode-java
Inline Method changes behavior for polymorphic method call
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 2.3k
- Forks
- 546
- Ø Merge
- 20 Std. 1 Min.
- Gemergte PRs (30 T.)
- 11
Beschreibung
Description
When using Inline Method on a method that is overridden in a subclass, VS Code Java performs the refactoring successfully, but the refactored program changes its runtime behavior.
The original program relies on dynamic dispatch. After inlining the superclass method body, the polymorphic method call is replaced with a fixed value, which breaks the original behavior.
Steps to reproduce
- Create the following Java code.
- Place the caret on method
fin classA. - Invoke Refactor -> Inline Method.
- Apply the inline refactoring.
- Run the program before and after refactoring.
Original code
package org.example;
public class Main {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
a1.test();
a2.test();
}
}
class A {
int f() {
return 1;
}
void test() {
int x = f(); // Inline target
System.out.println(x);
}
}
class B extends A {
@Override
int f() {
return 2;
}
}
Actual behavior
VS Code Java performs the inline refactoring. The refactored program still compiles, but its runtime behavior changes.
Original output:
1
2
Refactored output:
1
1
Refactored code generated by VS Code Java:
package org.example;
public class Main {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
a1.test();
a2.test();
}
}
class A {
void test() {
int x = 1;
System.out.println(x);
}
}
class B extends A {
@Override
int f() {
return 2;
}
}
The inline refactoring replaces the polymorphic method call f() with the body of A.f(). However, the call inside A.test() is dynamically dispatched at runtime. When test() is invoked on an instance of B, the original program calls B.f() and prints 2.
After refactoring, this dynamic dispatch is removed, so both calls print 1.
Expected behavior
Inline Method should preserve the runtime behavior of the original program.
The refactoring should either:
- reject the inline operation, or
- report a warning/error indicating that inlining this method may change behavior because the method is overridden and the call is dynamically dispatched.
It should not silently generate behavior-changing code.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Das Issue nennt keine Implementierungsdatei und keinen Test. Beginne damit, den Einstiegspunkt für das Refactoring Inline Method und die vorhandenen Regressionstests zu finden, reproduziere dann das A/B-Beispiel und verfolge, wie überschriebene Methoden und dynamisch dispatchte Aufrufe behandelt werden. Erledigt ist die Aufgabe, wenn die Operation abgelehnt wird oder vor der Verhaltensänderung warnt und ein Regressionstest die Ausgaben 1 und 2 abdeckt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- java, typescript
- Bereich
- devtools
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Ruhig
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 55/100