redhat-developer / redhat-developer/vscode-java
Inline Method changes behavior for polymorphic method call
まだ誰も着手していません。
- 主要言語
- TypeScript
- スター
- 2.3k
- フォーク
- 546
- 平均マージ
- 20時間 1分
- マージ済み PR(30日)
- 11
説明
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.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
この issue には実装ファイルもテストも記載されていません。まず Inline Method リファクタリングのエントリーポイントと既存の回帰テストを見つけ、次に A/B の例を再現して、オーバーライドされたメソッドと動的ディスパッチされる呼び出しがどのように扱われるかを追跡してください。完了条件は、操作が拒否されるか動作変更について警告し、出力 1 と 2 を対象とする回帰テストがあることです。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- java, typescript
- 領域
- devtools
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 静か
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 55/100