Inline Method changes behavior for polymorphic method call

Đang mở
#4,425 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
55/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
java, typescript
Lĩnh vực
devtools

Hướng nghiên cứu

Issue không nêu tệp triển khai hay bài kiểm thử nào. Hãy bắt đầu bằng cách xác định điểm vào của phép tái cấu trúc Inline Method và các bài kiểm thử hồi quy hiện có, sau đó tái hiện ví dụ A/B và theo dõi cách các phương thức bị ghi đè cùng các lời gọi được dispatch động được xử lý. Hoàn thành nghĩa là thao tác bị từ chối hoặc cảnh báo về thay đổi hành vi, với một bài kiểm thử hồi quy bao phủ các đầu ra 1 và 2.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug

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

  1. Create the following Java code.
  2. Place the caret on method f in class A.
  3. Invoke Refactor -> Inline Method.
  4. Apply the inline refactoring.
  5. 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:

  1. reject the inline operation, or
  2. 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.

Ngôn ngữ chính
TypeScript
Star
2.3k
Fork
547
Merge trung bình
20 giờ 1 phút
Pull request đã merge (30 ngày)
11

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của redhat-developer/vscode-java

Tất cả issue của redhat-developer/vscode-java

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.