2010-02-25 38 views
11

Vì vậy, đây là một đoạn mã sử dụng CodeModel mà tạo ra mã java:Chỉnh sửa/Sửa đổi tệp .java theo lập trình? (Không phải là tập tin .class)

JCodeModel cm = new JCodeModel(); 
    JDefinedClass dc = cm._class("foo.Bar"); 
    JMethod m = dc.method(0, int.class, "foo"); 
    m.body()._return(JExpr.lit(5)); 
    File f = new File("C:/target/classes"); 
    f.mkdirs(); 
    cm.build(f); 

Mã này tạo ra một file java:

package foo; 
public class Bar { 

     int foo() { 
     return 5; 
    } 
} 

Tuy nhiên, tôi KHÔNG muốn CodeModel tạo một tệp java mới cho tôi. Tôi đã có một tệp .java rồi và muốn thêm một vài dòng mã vào một phương thức bên trong nó. Vì vậy, tôi muốn API sửa đổi tệp java trực tiếp/tạo bản sao sửa đổi của nó. Có cách nào để làm việc này không?

+0

Có các lớp học một phần [của C#] trong java sẽ giúp ở một mức độ nào đó ... – Fakrudeen

+0

@Fakrudeen Vui lòng giải thích. – Jay

+0

C# cho phép định nghĩa lớp để mở rộng nhiều tệp. Nếu các thay đổi chỉ là phụ gia, bạn có thể xác định [tạo] chúng trong một tệp khác, thay vì sửa đổi tệp hiện có. Tất cả điều này là tranh luận cho bạn, như java không có các lớp học một phần. Đó là lý do tôi thêm nó làm bình luận. – Fakrudeen

Trả lời

10

Tôi biết đã lâu rồi kể từ bài đăng gốc, nhưng một trong những thư viện chuyển đổi Java tìm kiếm dễ tiếp cận hơn dường như là Spoon.

Từ Spoon Homepage:

Spoon cho phép bạn chuyển đổi (xem dưới đây) và phân tích (xem ví dụ) mã nguồn. Spoon cung cấp một metamodel Java hoàn chỉnh và hạt mịn trong đó bất kỳ phần tử chương trình nào (các lớp, phương thức, trường, câu lệnh, biểu thức ...) có thể được truy cập cả để đọc và sửa đổi. Spoon lấy làm mã nguồn đầu vào và tạo mã nguồn được chuyển đổi sẵn sàng để được biên dịch.

Cập nhật: Square cũng đã tạo thư viện tạo mã nguồn JavaPoet, API thông thạo trông đủ đơn giản để nắm bắt.

+1

thậm chí không nhớ lý do tại sao tôi đã hỏi câu hỏi này :) .. cảm ơn bạn đã trả lời nó - tôi đang thưởng cho câu trả lời của bạn! – Jay

+1

JavaPoet có thể đọc trong mã nguồn hiện tại không? Tôi không thể tìm thấy bất kỳ đề cập đến nó trong skimming JavaPoet README.md. – JohnC

+1

@ JohnC, xin lỗi, tôi đã không sử dụng JavaPoet tức giận, nhưng từ những gì tôi có thể thu thập, Spoon có vẻ phù hợp hơn với yêu cầu của bạn. Không có lý do gì để không kết hợp 2 thư viện để sửa đổi và phát sinh thuần túy (tức là công cụ thích hợp cho đúng công việc). –

2

Bạn thực sự cần phân tích đầy đủ mã bạn muốn sửa đổi để đảm bảo bạn chèn mã vào đúng vị trí. Tôi đã nghĩ rằng đặt cược tốt nhất của bạn sẽ là sử dụng một công cụ phân tích cú pháp hiện có cho phép mã được viết lại, thay vì cố gắng và làm điều gì đó bằng tay.

IDE Eclipse thực hiện điều gì đó như thế này để hỗ trợ tái cấu trúc mã. Điều này article có thể hữu ích.

-1

Điều bạn muốn là program transformation system. Đây là một công cụ phân tích cú pháp tệp nguồn của bạn và có thể áp dụng các phép biến đổi để sửa đổi nó, tạo lại mã nguồn với các sửa đổi.

Một hệ thống chuyển đổi nguồn-to-nguồn chấp nhận quy tắc của hình thức:

lhs -> rhs if cond 

nơi LHSRHS là mẫu souce cho mảnh hợp lệ của ngôn ngữ và cond kiểm tra rằng quy tắc là an toàn để áp dụng. (Xem xét "? X /? X -> 1 nếu? X ~ = 0"; bạn cần điều kiện để xác minh rằng bộ phận hợp lệ).

Một công cụ như vậy là DMS Software Reengineering Toolkit của chúng tôi. DMS có đầy đủ các trình phân tích cú pháp đầu cuối C, C++, C#, Java, COBOL, Python, PHP và ECMAScript (như nhiều ngôn ngữ ít được biết đến hơn) và có thể áp dụng trực tiếp các quy tắc đó. DMS cũng cung cấp việc xây dựng bảng biểu và kiểm soát và phân tích lưu lượng dữ liệu, vì chúng thường hữu ích trong việc xác định cond cho các quy tắc phức tạp. Nếu bạn muốn, bạn cũng có thể quay trở lại giao diện thủ tục "chuẩn" để truy cập các nút cây và sửa đổi AST.

+0

@Tôi cảm ơn. Tuy nhiên, tôi đang xem xét sử dụng các công cụ nguồn mở, chứ không phải những thứ thương mại. – Jay

+0

Vâng, bạn có thể thử TXL http://www.txl.ca hoặc Stratego http://www.strategoxt.org, cũng là các hệ thống chuyển đổi chương trình có quy tắc viết lại nguồn-nguồn. Những gì họ không có, mà tôi tin rằng về cơ bản là cần thiết để chuyển đổi các langau thủ tục, là bảng biểu tượng và các công cụ phân tích lưu lượng. Chúng tôi đã tìm thấy những điều này là không thể thiếu để thực hiện chuyển đổi chương trình quy mô lớn, đáng tin cậy. Bạn có thể tự mình thực hiện những công cụ này trong các công cụ OSS, nhưng nó có rất nhiều công việc. YMMV. –

+0

Chà. Câu trả lời 7 năm tuổi, giải quyết trực tiếp câu hỏi của OP, bao gồm việc cung cấp các lựa chọn thay thế nguồn mở khi OP làm rõ ràng trong bình luận của anh ta ... và * bây giờ * nó rút ra các downvotes? Tôi không cho rằng các downvoters sẵn sàng giải thích tại sao họ downvoted. –

2

... Tôi muốn API sửa đổi tệp java trực tiếp/tạo bản sao sửa đổi của nó. Có cách nào để làm việc này không?

JavaParser là API cho phép bạn đọc trong các tệp Java, sửa đổi chúng và nhận kết quả dưới dạng Chuỗi.

Cụ thể hơn, JavaParser phân tích tệp và xây dựng một AST (cây cú pháp trừu tượng). Sau đó bạn có thể sửa đổi JavaParser AST đại diện cho mã nguồn của bạn bằng cách sử dụng API và lấy biểu diễn String của AST.

Tôi có tệp .java rồi và muốn thêm một vài dòng mã vào một phương thức bên trong.

Dưới đây là một ví dụ của việc sử dụng JavaParser để thêm một dòng vào cuối của một cơ thể phương pháp và in kết quả:

class MyClass { 
    public static void someMethod() { 
     /* ... */ 
     // Lines will be added here: 
    } 

    public static void main(String[] args) { 
     String newStatement = "System.out.println(\"Hello world!\");" 
     File myClassSourceFile = new File("MyClass.java"); 
     CompilationUnit cu = JavaParser.parse(myClassSourceFile); 
     ClassOrInterfaceDeclaration classDeclaration = cu.getClassByName("MyClass").get(); 
     MethodDeclaration method = classDeclaration.getMethodsByName().get(0); 
     method.getBody().get().addStatement(newStatement); 

     // Print out the resulting Java source code. 
     System.out.println(cu.toString()); 
    } 
} 

CompilationUnit - Từ javadoc JavaParser của "Lớp này đại diện cho toàn bộ sưu tập Mỗi tệp java biểu thị một đơn vị biên dịch. "

LƯU Ý: Trong mã của bạn, bạn sẽ muốn thay thế các cuộc gọi Option.get() với xử lý tùy chọn thích hợp.

+1

Câu trả lời của bạn không rõ ràng với tôi nếu mã nguồn được tạo sẽ là bản gốc nhưng với các sửa đổi được bản địa hoá. Câu hỏi yêu cầu sửa đổi tối thiểu, có lẽ để ngăn chặn rất nhiều xung đột kiểm soát phiên bản. – neves

Các vấn đề liên quan