Jump to: navigation, search

Difference between revisions of "Developer's guide to building tools on top of AJDT and AspectJ"

Line 6: Line 6:
  
  
=== Obtaining crosscutting relationship information from AJDT ===
+
== Obtaining crosscutting relationship information from AJDT ==
  
 
(the following is derived from a post to the ajdt newsgroup on 26/10/2006)
 
(the following is derived from a post to the ajdt newsgroup on 26/10/2006)
Line 21: Line 21:
 
Crosscutting information can then be obtained from the AJModel class. Here's an example:  
 
Crosscutting information can then be obtained from the AJModel class. Here's an example:  
  
public class MyAdviceListener implements IAdviceChangedListener {  
+
  public class MyAdviceListener implements IAdviceChangedListener {  
 
     public void adviceChanged() {  
 
     public void adviceChanged() {  
 
         IProject project = AspectJPlugin.getDefault()  
 
         IProject project = AspectJPlugin.getDefault()  
Line 38: Line 38:
 
         }  
 
         }  
 
     }  
 
     }  
}  
+
  }  
  
 
For the "TJP Example" project (File > New > Other > AspectJ > AspectJ Examples), this prints:  
 
For the "TJP Example" project (File > New > Other > AspectJ > AspectJ Examples), this prints:  
  
build detected for project: P/TJP Example  
+
  build detected for project: P/TJP Example  
Relationship: around advises main  
+
  Relationship: around advises main  
Relationship: around advises foo  
+
  Relationship: around advises foo  
Relationship: around advises bar  
+
  Relationship: around advises bar  
Relationship: bar advised by around  
+
  Relationship: bar advised by around  
Relationship: foo advised by around  
+
  Relationship: foo advised by around  
Relationship: main advised by around  
+
  Relationship: main advised by around  
  
 
As you can see, you get the relationship in both directions. See AJRelationshipManager for the full list of relationships, so you can just ask for the relationship types you're interested in.  
 
As you can see, you get the relationship in both directions. See AJRelationshipManager for the full list of relationships, so you can just ask for the relationship types you're interested in.  
Line 60: Line 60:
  
  
=== Using the AspectJ AST parser ===
+
== Using the AspectJ AST parser ==
  
Basic example, taken from bug 88861:
+
Basic example, taken from [https://bugs.eclipse.org/bugs/show_bug.cgi?id=88861 bug 88861]
https://bugs.eclipse.org/bugs/show_bug.cgi?id=88861
+
  
 
import java.util.*;
 
import java.util.*;
 
import org.aspectj.org.eclipse.jdt.core.dom.*;
 
import org.aspectj.org.eclipse.jdt.core.dom.*;
  
public class Program {
+
  public class Program {
 
+
    public static void main(String []argv) {
  public static void main(String []argv) {
+
      ASTParser parser = ASTParser.newParser(AST.JLS2);
    ASTParser parser = ASTParser.newParser(AST.JLS2);
+
      parser.setCompilerOptions(new HashMap());
    parser.setCompilerOptions(new HashMap());
+
      parser.setSource(argv[0].toCharArray());
    parser.setSource(argv[0].toCharArray());
+
      CompilationUnit cu2 = (CompilationUnit) parser.createAST(null);
    CompilationUnit cu2 = (CompilationUnit) parser.createAST(null);
+
      AjNaiveASTFlattener visitor = new AjNaiveASTFlattener();
    AjNaiveASTFlattener visitor = new AjNaiveASTFlattener();
+
      cu2.accept(visitor);
    cu2.accept(visitor);
+
      System.err.println(visitor.getResult());
    System.err.println(visitor.getResult());
+
    }
 
   }
 
   }
}
 
  
 
I can now compile that program (outside of eclipse..) and if I run it:
 
I can now compile that program (outside of eclipse..) and if I run it:
  
java Program "public aspect X { pointcut p(): call(* *(..));}"
+
  java Program "public aspect X { pointcut p(): call(* *(..));}"
  
 
then it prints:
 
then it prints:
  
public aspect X {
+
  public aspect X {
  pointcut p():call(* *(..));
+
    pointcut p():call(* *(..));
}
+
  }
  
See also bug 110465: Continue AST work
+
See also [https://bugs.eclipse.org/bugs/show_bug.cgi?id=110465 bug 110465: Continue AST work]
https://bugs.eclipse.org/bugs/show_bug.cgi?id=110465
+
  
  
 
----
 
----
  
=== Known limitations, bugs, and outstanding issues===
+
== Known limitations, bugs, and outstanding issues==
  
  
 
Limitation: There is currently no AST support for resolving type bindings:
 
Limitation: There is currently no AST support for resolving type bindings:
 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=146528
 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=146528
 +
 +
----
 +
 +
== Anything else? ==
 +
 +
----
 +
----
 +
 +
----
  
 
----
 
----

Revision as of 10:14, 4 January 2007

This page is intended to aid anyone developing tools to extend or work with AJDT/AspectJ. Please contribute to this page with any relevant information, such as example code using the AJDT and/or AspectJ APIs.

--Mpchapman.gmail.com 10:05, 4 January 2007 (EST)



Obtaining crosscutting relationship information from AJDT

(the following is derived from a post to the ajdt newsgroup on 26/10/2006)

If you're developing an eclipse plugin and require access to crosscutting information whenever a project is built, you can register a listener with AJDT. Your plug-in will need to depend on org.eclipse.ajdt.core, org.eclipse.core.resources and org.eclipse.jdt.core. In the org.eclipse.ajdt.core plug-in there is an IAdviceChangedListener interface with a single adviceChanged() method.

Register this with the AJBuilder class like this (in your plug-in's start() method for example):

   AJBuilder.addAdviceListener(new MyAdviceListener()); 

Currently (AJDT 1.4) this is called after every build of an AspectJ project (i.e. every *potential* advice change). In a future release this may be optimized to be only called if the advice has actually changed. AJDT/UI uses this mechanism to update the orange arrow image decorator.

Crosscutting information can then be obtained from the AJModel class. Here's an example:

 public class MyAdviceListener implements IAdviceChangedListener { 
   public void adviceChanged() { 
       IProject project = AspectJPlugin.getDefault() 
               .getCurrentProject(); 
       System.out.println("build detected for project: " + project); 
       AJRelationshipType[] relsTypes = AJRelationshipManager 
               .getAllRelationshipTypes(); 
       List rels = AJModel.getInstance().getAllRelationships( 
               project, relsTypes); 
       for (Iterator iter = rels.iterator(); iter.hasNext();) { 
           AJRelationship ajrel = (AJRelationship) iter.next(); 
           System.out.println("Relationship: " 
                   + ajrel.getSource().getElementName() + " " 
                   + ajrel.getRelationship().getDisplayName() + " " 
                   + ajrel.getTarget().getElementName()); 
       } 
   } 
 } 

For the "TJP Example" project (File > New > Other > AspectJ > AspectJ Examples), this prints:

 build detected for project: P/TJP Example 
 Relationship: around advises main 
 Relationship: around advises foo 
 Relationship: around advises bar 
 Relationship: bar advised by around 
 Relationship: foo advised by around 
 Relationship: main advised by around 

As you can see, you get the relationship in both directions. See AJRelationshipManager for the full list of relationships, so you can just ask for the relationship types you're interested in.

AJRelationship.getSource() and getTarget() return instances of IJavaElement so you can obtain further information from that, such as the parent or underlying resource.





Using the AspectJ AST parser

Basic example, taken from bug 88861

import java.util.*; import org.aspectj.org.eclipse.jdt.core.dom.*;

 public class Program {
   public static void main(String []argv) {
     ASTParser parser = ASTParser.newParser(AST.JLS2);
     parser.setCompilerOptions(new HashMap());
     parser.setSource(argv[0].toCharArray());
     CompilationUnit cu2 = (CompilationUnit) parser.createAST(null);
     AjNaiveASTFlattener visitor = new AjNaiveASTFlattener();
     cu2.accept(visitor);
     System.err.println(visitor.getResult());
   }
 }

I can now compile that program (outside of eclipse..) and if I run it:

 java Program "public aspect X { pointcut p(): call(* *(..));}"

then it prints:

 public aspect X {
    pointcut p():call(* *(..));
 }

See also bug 110465: Continue AST work



Known limitations, bugs, and outstanding issues

Limitation: There is currently no AST support for resolving type bindings: https://bugs.eclipse.org/bugs/show_bug.cgi?id=146528


Anything else?