You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/05/08 21:33:41 UTC

svn commit: r773066 - in /incubator/pivot/trunk/wtk/src/pivot/wtkx: BindMethodProcessor.java BindProcessor.java Bindable.java

Author: tvolkert
Date: Fri May  8 19:33:39 2009
New Revision: 773066

URL: http://svn.apache.org/viewvc?rev=773066&view=rev
Log:
changed BindMethodProcessor to define the overload but not touch the base bind(); added BindMethodProcessor.BIND_OVERLOAD_NAME, to be used by package classes

Modified:
    incubator/pivot/trunk/wtk/src/pivot/wtkx/BindMethodProcessor.java
    incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java
    incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java

Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/BindMethodProcessor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/BindMethodProcessor.java?rev=773066&r1=773065&r2=773066&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/BindMethodProcessor.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/BindMethodProcessor.java Fri May  8 19:33:39 2009
@@ -38,7 +38,7 @@
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.parser.Parser;
 import com.sun.tools.javac.parser.Scanner;
-import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.TreeTranslator;
 import com.sun.tools.javac.util.Context;
 import com.sun.source.util.Trees;
@@ -46,14 +46,11 @@
 /**
  * Annotation processor that re-writes the base {@link Bindable#bind()}
  * implementation such that it calls into a newly defined <tt>protected
- * void bind(Map)</tt> method, thus paving the way for {@link BindProcessor} to
- * process subclasses of <tt>Bindable</tt>.
+ * void __bind(Map)</tt> method, thus paving the way for {@link BindProcessor}
+ * to process subclasses of <tt>Bindable</tt>.
  * <p>
- * Note that this class works in close tandem with <tt>BindProcessor</tt> in
- * that they share a mutual contract. They are distinct because this processor
- * lives in the same sub-project that it must process, meaning that it gets
- * compiled separately, before any other classes in its project. However,
- * changes to one class should be coordinated with changes to the other.
+ * Note that this class works in close tandem with <tt>BindProcessor</tt> and
+ * <tt>Bindable</tt> in that they share a mutual contract.
  *
  * @author tvolkert
  */
@@ -71,23 +68,25 @@
     static @interface BindMethod {
     }
 
+    static final String BIND_OVERLOAD_NAME = "__bind";
+
     /**
-     * This actually does the work of bind method re-writing.
+     * This actually does the work of overloaded bind method injection.
      *
      * @author tvolkert
      */
-    private class BindMethodRewriter extends TreeTranslator {
+    private class BindOverloadInjector extends TreeTranslator {
         private ArrayStack<Boolean> stack = new ArrayStack<Boolean>();
 
         /**
-         * Adds a bind overload signature (<tt>protected void bind(Map)</tt>)
+         * Adds a bind overload signature (<tt>protected void __bind(Map)</tt>)
          * to the class containing the base bind implementation.
          *
          * @param classDeclaration
          * The AST class declaration node
          */
         @Override
-        public void visitClassDef(JCTree.JCClassDecl classDeclaration) {
+        public void visitClassDef(JCClassDecl classDeclaration) {
             stack.push(false);
             super.visitClassDef(classDeclaration);
             boolean addOverload = stack.pop();
@@ -96,15 +95,17 @@
                 // Create source code containing out bind overload
                 StringBuilder sourceCode = new StringBuilder();
                 sourceCode.append("class _A {");
-                sourceCode.append("protected void __bind__(pivot.collections.Map<String,pivot.wtkx.WTKXSerializer> m) {}");
+                sourceCode.append("protected void ");
+                sourceCode.append(BIND_OVERLOAD_NAME);
+                sourceCode.append("(pivot.collections.Map<String,pivot.wtkx.WTKXSerializer> m) {}");
                 sourceCode.append("}");
 
                 // Parse the source code and extract the method declaration
                 Scanner scanner = scannerFactory.newScanner(sourceCode.toString());
                 Parser parser = parserFactory.newParser(scanner, false, false);
-                JCTree.JCCompilationUnit parsedCompilationUnit = parser.compilationUnit();
-                JCTree.JCClassDecl parsedClassDeclaration = (JCTree.JCClassDecl)parsedCompilationUnit.defs.head;
-                JCTree.JCMethodDecl parsedMethodDeclaration = (JCTree.JCMethodDecl)parsedClassDeclaration.defs.head;
+                JCCompilationUnit parsedCompilationUnit = parser.compilationUnit();
+                JCClassDecl parsedClassDeclaration = (JCClassDecl)parsedCompilationUnit.defs.head;
+                JCMethodDecl parsedMethodDeclaration = (JCMethodDecl)parsedClassDeclaration.defs.head;
 
                 // Add the AST method declaration to our class
                 classDeclaration.defs = classDeclaration.defs.prepend(parsedMethodDeclaration);
@@ -113,42 +114,19 @@
 
         /**
          * Checks for the <tt>@BindMethod</tt> annotation on a method
-         * (signalling the base class' implementation). When found, this
-         * re-writes the method's body such that it calls into the
-         * <tt>bind(Map)</tt> overload (which will be defined in
-         * <tt>visitClassDef</tt>), thus clearing the way for us to override
-         * <tt>bind(Map)</tt> in bindable subclasses with inline
-         * WTKX binding implementations.
+         * (signalling the base class' implementation), and marks the current
+         * stack frame when it finds the annotation.
          *
          * @param methodDeclaration
          * The AST method declaration node
          */
         @Override
-        public void visitMethodDef(JCTree.JCMethodDecl methodDeclaration) {
+        public void visitMethodDef(JCMethodDecl methodDeclaration) {
             super.visitMethodDef(methodDeclaration);
 
             Element methodElement = methodDeclaration.sym;
             if (methodElement != null) {
-                BindMethod bindMethod = methodElement.getAnnotation(BindMethod.class);
-
-                if (bindMethod != null) {
-                    // Generate the re-written source code for bind()
-                    StringBuilder sourceCode = new StringBuilder("{");
-                    sourceCode.append("pivot.collections.HashMap<String,pivot.wtkx.WTKXSerializer> m = ");
-                    sourceCode.append("new pivot.collections.HashMap<String,pivot.wtkx.WTKXSerializer>();");
-                    sourceCode.append("__bind__(m);");
-                    sourceCode.append("}");
-
-                    // Parse the source code into a AST block
-                    Scanner scanner = scannerFactory.newScanner(sourceCode.toString());
-                    Parser parser = parserFactory.newParser(scanner, false, false);
-                    JCTree.JCBlock parsedMethodBody = parser.block();
-
-                    // Set the AST block as the body of the bind() method
-                    methodDeclaration.body = parsedMethodBody;
-
-                    // Notify the stack that this is the correct level to add
-                    // our bind overload
+                if (methodElement.getAnnotation(BindMethod.class) != null) {
                     stack.poke(true);
                 }
             }
@@ -159,7 +137,7 @@
     private Context context;
     private Scanner.Factory scannerFactory;
     private Parser.Factory parserFactory;
-    private BindMethodRewriter bindMethodRewriter = new BindMethodRewriter();
+    private BindOverloadInjector bindOverloadInjector = new BindOverloadInjector();
 
     @Override
     public synchronized void init(ProcessingEnvironment processingEnvironment) {
@@ -191,9 +169,9 @@
             }
 
             for (Element classElement : classElements) {
-                // Visit the AST class node with our BindMethodRewriter visitor
-                JCTree tree = (JCTree)trees.getTree(classElement);
-                tree.accept(bindMethodRewriter);
+                // Visit the AST class node with our BindOverloadInjector visitor
+                JCClassDecl classDeclaration = (JCClassDecl)trees.getTree(classElement);
+                classDeclaration.accept(bindOverloadInjector);
             }
         }
 

Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java?rev=773066&r1=773065&r2=773066&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java Fri May  8 19:33:39 2009
@@ -16,8 +16,6 @@
  */
 package pivot.wtkx;
 
-import java.util.Set;
-
 import javax.annotation.processing.AbstractProcessor;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.annotation.processing.RoundEnvironment;
@@ -45,7 +43,7 @@
 import com.sun.source.util.Trees;
 
 /**
- * Annotation processor that injects <tt>__bind__(Map)</tt> overrides into
+ * Annotation processor that injects overridden bind overload methods into
  * classes that use the <tt>@Load</tt> and <tt>@Bind</tt> annotations to
  * perform WTKX loading and binding.
  *
@@ -105,7 +103,7 @@
          * list. After <tt>reconcile</tt> has been called, any bind fields that
          * remain in the stranded list are assumed to be bound to
          * <tt>public</tt> or <tt>protected</tt> load fields in a superclass.
-         * It is up to the <tt>__bind__</tt> method to handle these stranded
+         * It is up to the overload method to handle these stranded
          * bind fields correctly.
          */
         public List<JCVariableDecl> getStrandedBindFields() {
@@ -218,7 +216,7 @@
         private ArrayStack<AnnotationDossier> stack = new ArrayStack<AnnotationDossier>();
 
         /**
-         * Injects an override implementation of the <tt>__bind__(Map)</tt>
+         * Injects an override implementation of the overloaded bind
          * method into the specified class if any member variables are found to
          * be annotated with the <tt>@Load</tt> or <tt>@Bind</tt> annotations.
          *
@@ -245,8 +243,12 @@
                 // creating the source code buffer
                 StringBuilder sourceCode = new StringBuilder("class _A {");
                 sourceCode.append("@Override ");
-                sourceCode.append("protected void __bind__(pivot.collections.Map<String,pivot.wtkx.WTKXSerializer> namedSerializers) {");
-                sourceCode.append("super.__bind__(namedSerializers);");
+                sourceCode.append("protected void ");
+                sourceCode.append(BindMethodProcessor.BIND_OVERLOAD_NAME);
+                sourceCode.append("(pivot.collections.Map<String,pivot.wtkx.WTKXSerializer> namedSerializers) {");
+                sourceCode.append("super.");
+                sourceCode.append(BindMethodProcessor.BIND_OVERLOAD_NAME);
+                sourceCode.append("(namedSerializers);");
 
                 // Local variable declarations
                 sourceCode.append("pivot.wtkx.WTKXSerializer wtkxSerializer;");
@@ -454,7 +456,7 @@
     }
 
     @Override
-    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
+    public boolean process(java.util.Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
         if (!roundEnvironment.processingOver()) {
             for (Element rootElement : roundEnvironment.getRootElements()) {
                 if (rootElement.getKind() == ElementKind.CLASS) {

Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java?rev=773066&r1=773065&r2=773066&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java Fri May  8 19:33:39 2009
@@ -73,7 +73,8 @@
     protected final void bind() throws BindException {
         Method bindOverload = null;
         try {
-            bindOverload = getClass().getDeclaredMethod("__bind__", new Class<?>[] {Map.class});
+            bindOverload = getClass().getDeclaredMethod(BindMethodProcessor.BIND_OVERLOAD_NAME,
+                new Class<?>[] {Map.class});
         } catch(NoSuchMethodException exception) {
             // No-op
         }