2010-07-28 40 views
6

Gần đây tôi đã cần sửa đổi một số mã Java (thêm các phương thức, thay đổi chữ ký của một số trường và loại bỏ các phương thức) và tôi nghĩ rằng tất cả điều này có thể được thực hiện mặc dù việc sử dụng SDK của Eclipse AST.Sử dụng AST Eclipse

Tôi biết từ một số nghiên cứu về cách phân tích cú pháp trong tệp nguồn nhưng tôi không biết cách thực hiện những điều được đề cập ở trên. Có ai biết một hướng dẫn tốt hay ai đó có thể cho tôi một lời giải thích ngắn gọn về cách giải quyết những vấn đề này?

Thanks a lot,

ExtremeCoder


Edit:

bây giờ tôi đã bắt đầu để xem xét thêm vào các JCodeModel và tôi nghĩ rằng điều này có thể dễ dàng hơn để sử dụng nhưng tôi không biết nếu một tài liệu tồn tại có thể được nạp vào nó?

Nếu điều này có thể hiệu quả, hãy cho tôi biết;)

Xin cảm ơn một lần nữa.

Trả lời

4

Tôi sẽ không đăng toàn bộ mã nguồn lên vấn đề này tại đây vì nó khá dài nhưng tôi sẽ khiến mọi người bắt đầu.

Tất cả các tài liệu mà bạn sẽ cần đang ở đây:. http://publib.boulder.ibm.com/infocenter/iadthelp/v6r0/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/package-summary.html

Document document = new Document("import java.util.List;\n\nclass X\n{\n\n\tpublic void deleteme()\n\t{\n\t}\n\n}\n"); 
ASTParser parser = ASTParser.newParser(AST.JLS3); 
parser.setSource(document.get().toCharArray()); 
CompilationUnit cu = (CompilationUnit)parser.createAST(null); 
cu.recordModifications(); 

Điều đó sẽ tạo ra một đơn vị biên dịch cho bạn từ các mã nguồn mà bạn vượt qua trong

Bây giờ đây là một chức năng đơn giản mà in ra tất cả các phương pháp bên trong các định nghĩa lớp trong những gì bạn đã vượt qua:

List<AbstractTypeDeclaration> types = cu.types(); 
for(AbstractTypeDeclaration type : types) { 
    if(type.getNodeType() == ASTNode.TYPE_DECLARATION) { 
     // Class def found 
     List<BodyDeclaration> bodies = type.bodyDeclarations(); 
     for(BodyDeclaration body : bodies) { 
      if(body.getNodeType() == ASTNode.METHOD_DECLARATION) { 
       MethodDeclaration method = (MethodDeclaration)body; 
       System.out.println("method declaration: "); 
       System.out.println("name: " + method.getName().getFullyQualifiedName()); 
       System.out.println("modifiers: " + method.getModifiers()); 
       System.out.println("return type: " + method.getReturnType2().toString()); 
      } 
     } 
    } 
} 

Điều này sẽ giúp bạn bắt đầu.

Phải mất một thời gian để làm quen với điều này (rất nhiều trong trường hợp của tôi). Nhưng nó hoạt động và là phương pháp tốt nhất mà tôi có thể nắm được.

Chúc may mắn;)

ExtremeCoder


Edit:

Trước khi tôi quên, đây là hàng nhập khẩu mà tôi sử dụng để làm việc này (tôi mất khá nhiều thời gian để có những tổ chức này):

org.eclipse.jdt.core_xxxx.jar 
org.eclipse.core.resources_xxxx.jar 
org.eclipse.core.jobs_xxxx.jar 
org.eclipse.core.runtime_xxxx.jar 
org.eclipse.core.contenttype_xxxx.jar 
org.eclipse.equinox.common_xxxx.jar 
org.eclipse.equinox.preferences_xxxx.jar 
org.eclipse.osgi_xxxx.jar 
org.eclipse.text_xxxx.jar 

Nơi xxxx đại diện cho một số phiên bản.

1

Bạn có thể làm điều này với Eclipse bằng cách gọi API cho phép bạn thao tác với AST.

Hoặc bạn có thể áp dụng các phép biến đổi chương trình để đạt được hiệu quả theo cách không phụ thuộc vào các chi tiết vi mô của AST.

Ví dụ bạn có thể viết sự chuyển đổi chương trình sau đây:

add_int_parameter(p:parameter_list, i: identifier): parameters -> parameters 
    " \p " -> " \p , int \i"; 

để thêm một tham số số nguyên với một cái tên tùy ý vào một danh sách tham số. Điều này đạt được hiệu quả tương tự như một tập hợp toàn bộ các cuộc gọi API nhưng nó có thể đọc được nhiều hơn vì nó nằm trong cú pháp bề mặt của ngôn ngữ của bạn (trong trường hợp này là Java).

DMS Software Reengineering Toolkit của chúng tôi có thể chấp nhận program transformations và áp dụng chúng cho nhiều ngôn ngữ, bao gồm Java.