Package com.sun.tools.javac.processing

Source Code of com.sun.tools.javac.processing.PrintingProcessor$PrintingElementVisitor

/*
* @(#)PrintingProcessor.java  1.9 07/03/21
*
* Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/

package com.sun.tools.javac.processing;

import com.sun.tools.javac.util.Version;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import static javax.lang.model.element.ElementKind.*;
import static javax.lang.model.element.NestingKind.*;
import javax.lang.model.type.*;
import javax.lang.model.util.*;
import static javax.lang.model.util.ElementFilter.*;

import java.io.PrintWriter;
import java.io.Writer;
import java.util.*;

/**
* A processor which prints out elements.  Used to implement the
* -Xprint option; the included visitor class is used to implement
* Elements.printElements.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@Version("@(#)PrintingProcessor.java  1.9 07/03/21")
public class PrintingProcessor extends AbstractProcessor {
    private static my.Debug DEBUG=new my.Debug(my.Debug.PrintingProcessor);//我加上的
   
    PrintWriter writer;

    public PrintingProcessor() {
  super();
  writer = new PrintWriter(System.out);
    }

    public void setWriter(Writer w) {
  writer = new PrintWriter(w);
    }

    @Override
    public boolean process(Set<? extends TypeElement> tes,
         RoundEnvironment renv) {
        DEBUG.P(this,"process(2)");
       
  //我加上的        
  JavacRoundEnvironment jre=(JavacRoundEnvironment)renv;
  for(Element element : jre.getRootElements()) {
      print(element);
  }
  /*
  for(Element element : renv.getRootElements()) {
      print(element);
  }
  */
       
        DEBUG.P(0,this,"process(2)");
  // Just print the elements, nothing more to do.
  return true;
    }

    void print(Element element) {
  new PrintingElementVisitor(writer, processingEnv.getElementUtils()).
      visit(element).flush();
    }

    /**
     * Used for the -Xprint option and called by Elements.printElements
     */
    public static class PrintingElementVisitor
  extends SimpleElementVisitor6<PrintingElementVisitor, Boolean> {
  int indentation; // Indentation level;
  final PrintWriter writer;
  final Elements elementUtils;

  public PrintingElementVisitor(Writer w, Elements elementUtils) {
      super();
      this.writer = new PrintWriter(w);
      this.elementUtils = elementUtils;
      indentation = 0;
  }

  @Override
  protected PrintingElementVisitor defaultAction(Element e, Boolean newLine) {
      if (newLine != null && newLine)
    writer.println();
      printDocComment(e);
      printModifiers(e);
      return this;
  }

  @Override
  public PrintingElementVisitor visitExecutable(ExecutableElement e, Boolean p) {
      ElementKind kind = e.getKind();
      
      if (kind != STATIC_INIT &&
    kind != INSTANCE_INIT) {
    Element enclosing = e.getEnclosingElement();
   
    // Don't print out the constructor of an anonymous class
    if (kind == CONSTRUCTOR &&
        enclosing != null &&
        NestingKind.ANONYMOUS ==
        // Use an anonymous class to determine anonymity!
        (new SimpleElementVisitor6<NestingKind, Void>() {
      @Override
      public NestingKind visitType(TypeElement e, Void p) {
          return e.getNestingKind();
      }
        }).visit(enclosing))
        return this;

    defaultAction(e, true);
    printFormalTypeParameters(e);

    switch(kind) {
        case CONSTRUCTOR:
        // Print out simple name of the class
        writer.print(e.getEnclosingElement().getSimpleName());
        break;
       
        case METHOD:
        writer.print(e.getReturnType().toString());
        writer.print(" ");
        writer.print(e.getSimpleName().toString());
        break;
    }

    writer.print("(");
    printParameters(e);
    writer.print(")");
    AnnotationValue defaultValue = e.getDefaultValue();
    if (defaultValue != null)
        writer.print(" default " + defaultValue);

    printThrows(e);
    writer.println(";");
      }
      return this;
  }


  @Override
  public PrintingElementVisitor visitType(TypeElement e, Boolean p) {
      ElementKind kind = e.getKind();
      NestingKind nestingKind = e.getNestingKind();
     
      if (NestingKind.ANONYMOUS == nestingKind) {
    // Print out an anonymous class in the style of a
    // class instance creation expression rather than a
    // class declaration.
    writer.print("new ");

    // If the anonymous class implements an interface
    // print that name, otherwise print the superclass.
    List<? extends TypeMirror> interfaces = e.getInterfaces();
    if (!interfaces.isEmpty())
        writer.print(interfaces.get(0));
    else
        writer.print(e.getSuperclass());

    writer.print("(");
    // Anonymous classes that implement an interface can't
    // have any constructor arguments.
    if (interfaces.isEmpty()) {
        // Print out the parameter list from the sole
        // constructor.  For now, don't try to elide any
        // synthetic parameters by determining if the
        // anonymous class is in a static context, etc.
        List<? extends ExecutableElement> constructors =
      ElementFilter.constructorsIn(e.getEnclosedElements());
   
        if (!constructors.isEmpty())
      printParameters(constructors.get(0));
    }
    writer.print(")");
      } else {
    if (nestingKind == TOP_LEVEL) {
        PackageElement pkg = elementUtils.getPackageOf(e);
        if (!pkg.isUnnamed())
      writer.print("package " + pkg.getQualifiedName() + ";\n");
    }

    defaultAction(e, true);

    switch(kind) {
    case ANNOTATION_TYPE:
        writer.print("@interface");
        break;
    default:
        writer.print(kind.toString().toLowerCase());
    }
    writer.print(" ");
    writer.print(e.getSimpleName());

    printFormalTypeParameters(e);

    // Print superclass information if informative
    if (kind == CLASS) {
        TypeMirror supertype = e.getSuperclass();
        if (supertype.getKind() != TypeKind.NONE) {
      TypeElement e2 = (TypeElement)
          ((DeclaredType) supertype).asElement();
      if (e2.getSuperclass().getKind() != TypeKind.NONE)
          writer.print(" extends " + supertype);
        }
    }
     
    printInterfaces(e);
      }
      writer.println(" {");
      indentation++;
     
      if (kind == ENUM) {
    List<Element> enclosedElements =
        new ArrayList<Element>(e.getEnclosedElements());
    List<Element> enumConstants = new ArrayList<Element>();
    for(Element element : enclosedElements) {
        if (element.getKind() == ENUM_CONSTANT)
      enumConstants.add(element);
    }
   
    int i;
    for(i = 0; i < enumConstants.size()-1; i++) {
        this.visit(enumConstants.get(i), true);
        writer.print(",");
    }
    if (i >= 0 ) {
        this.visit(enumConstants.get(i), true);
        writer.print(";");
    }
   
    enclosedElements.removeAll(enumConstants);
    for(Element element : enclosedElements)
        this.visit(element);
      } else {
    for(Element element : e.getEnclosedElements())
        this.visit(element);
      }

      indentation--;
      indent();
      writer.println("}");
      return this;
  }

  @Override
  public PrintingElementVisitor visitVariable(VariableElement e, Boolean newLine) {
      ElementKind kind = e.getKind();
      defaultAction(e, newLine);

      if (kind == ENUM_CONSTANT)
    writer.print(e.getSimpleName());
      else {
    writer.print(e.asType().toString() + " " + e.getSimpleName() );
    Object constantValue  = e.getConstantValue();
    if (constantValue != null) {
        writer.print(" = ");
        writer.print(elementUtils.getConstantExpression(constantValue));
    }
    writer.println(";");
      }
      return this;
  }

  @Override
  public PrintingElementVisitor visitTypeParameter(TypeParameterElement e, Boolean p) {
      writer.print(e.getSimpleName());
      return this;
  }

  // Should we do more here?
  @Override
  public PrintingElementVisitor visitPackage(PackageElement e, Boolean p) {
      defaultAction(e, false);
      if (!e.isUnnamed())
    writer.println("package " + e.getQualifiedName() + ";");
      else
    writer.println("// Unnamed package");
      return this;
  }

  public void flush() {
      writer.flush();
  }

  private void printDocComment(Element e) {
      String docComment = elementUtils.getDocComment(e);

      if (docComment != null) {
    // Break comment into lines
    java.util.StringTokenizer st = new StringTokenizer(docComment,
                  "\n\r");
    indent();
    writer.println("/**");
   
    while(st.hasMoreTokens()) {
        indent();
        writer.print(" *");
        writer.println(st.nextToken());
    }

    indent();
    writer.println(" */");
      }
  }

  private void printModifiers(Element e) {
      ElementKind kind = e.getKind();
      if (kind == PARAMETER) {
    printAnnotationsInline(e);
      } else {
    printAnnotations(e);
    indent();
      }

      if (kind == ENUM_CONSTANT)
    return;

      Set<Modifier> modifiers = new LinkedHashSet<Modifier>();
      modifiers.addAll(e.getModifiers());

      switch (kind) {
      case ANNOTATION_TYPE:
      case INTERFACE:
    modifiers.remove(Modifier.ABSTRACT);
    break;

      case ENUM:
    modifiers.remove(Modifier.FINAL);
    modifiers.remove(Modifier.ABSTRACT);
    break;

      case METHOD:
      case FIELD:
    Element enclosingElement = e.getEnclosingElement();
    if (enclosingElement != null &&
        enclosingElement.getKind().isInterface()) {
        modifiers.remove(Modifier.PUBLIC);
        modifiers.remove(Modifier.ABSTRACT); // only for methods
        modifiers.remove(Modifier.STATIC);   // only for fields
        modifiers.remove(Modifier.FINAL);    // only for fields
    }
    break;

      }

      for(Modifier m: modifiers) {
    writer.print(m.toString() + " ");
      }
  }
 
  private void printFormalTypeParameters(ExecutableElement executable) {
      printFormalTypeParameters(executable.getTypeParameters(), true);
  }

  private void printFormalTypeParameters(TypeElement type) {
      printFormalTypeParameters(type.getTypeParameters(), false);
  }

  private void printFormalTypeParameters(List<? extends TypeParameterElement> typeParams,
                 boolean pad) {
      if (typeParams.size() > 0) {
    writer.print("<");

    boolean first = true;
    for(TypeParameterElement tpe: typeParams) {
        if (!first)
      writer.print(", ");
        writer.print(tpe.toString());
        first = false;
    }

    writer.print(">");
    if (pad)
        writer.print(" ");
      }
  }

  private void printAnnotationsInline(Element e) {
      List<? extends AnnotationMirror> annots = e.getAnnotationMirrors();
      for(AnnotationMirror annotationMirror : annots) {
    writer.print(annotationMirror);
    writer.print(" ");
      }
  }

  private void printAnnotations(Element e) {
      List<? extends AnnotationMirror> annots = e.getAnnotationMirrors();
      for(AnnotationMirror annotationMirror : annots) {
    indent();
    writer.println(annotationMirror);
      }
  }

  // TODO: Refactor
  private void printParameters(ExecutableElement e) {
      List<? extends VariableElement> parameters = e.getParameters();
      int size = parameters.size();

      switch (size) {
      case 0:
    break;
   
      case 1:
    for(VariableElement parameter: parameters) {
        printModifiers(parameter);

        if (e.isVarArgs() ) {
      TypeMirror tm = parameter.asType();
      if (tm.getKind() != TypeKind.ARRAY)
          throw new AssertionError("Var-args parameter is not an array type: " + tm);
      writer.print((ArrayType.class.cast(tm)).getComponentType() );
      writer.print("...");
        } else
      writer.print(parameter.asType());
        writer.print(" " + parameter.getSimpleName());
    }
    break;

      default:
    {
        int i = 1;
        for(VariableElement parameter: parameters) {
      if (i == 2)
          indentation++;

      if (i > 1)
          indent();

      printModifiers(parameter);

      if (i == size && e.isVarArgs() ) {
          TypeMirror tm = parameter.asType();
          if (tm.getKind() != TypeKind.ARRAY)
        throw new AssertionError("Var-args parameter is not an array type: " + tm);
            writer.print((ArrayType.class.cast(tm)).getComponentType() );

          writer.print("...");
      } else
          writer.print(parameter.asType());
      writer.print(" " + parameter.getSimpleName());

      if (i < size)
          writer.println(",");
         
      i++;
        }
       
        if (parameters.size() >= 2)
      indentation--;
    }
    break;
      }
  }

  private void printInterfaces(TypeElement e) {
      ElementKind kind = e.getKind();
     
      if(kind != ANNOTATION_TYPE) {
    List<? extends TypeMirror> interfaces = e.getInterfaces();
    if (interfaces.size() > 0) {
        writer.print((kind.isClass() ? " implements" : " extends"));
   
        boolean first = true;
        for(TypeMirror interf: interfaces) {
      if (!first)
          writer.print(",");
      writer.print(" ");
      writer.print(interf.toString());
      first = false;
        }
    }
      }
  }

  private void printThrows(ExecutableElement e) {
      List<? extends TypeMirror> thrownTypes = e.getThrownTypes();
      final int size = thrownTypes.size();
      if (size != 0) {
    writer.print(" throws");

    int i = 1;
    for(TypeMirror thrownType: thrownTypes) {
        if (i == 1)
      writer.print(" ");

        if (i == 2)
      indentation++;

        if (i >= 2)
      indent();

        writer.print(thrownType);
       
        if (i != size)
      writer.println(", ");

        i++;
    }

    if (size >= 2)
        indentation--;
      }
  }

  private static final String [] spaces = {
      "",
      "  ",
      "    ",
      "      ",
      "        ",
      "          ",
      "            ",
      "              ",
      "                ",
      "                  ",
      "                    "
  };

  private void indent() {
      int indentation = this.indentation;
      if (indentation < 0)
    return;
      final int maxIndex = spaces.length - 1;
     
      while (indentation > maxIndex) {
    writer.print(spaces[maxIndex]);
    indentation -= maxIndex;
      }
      writer.print(spaces[indentation]);
  }

    }
}
TOP

Related Classes of com.sun.tools.javac.processing.PrintingProcessor$PrintingElementVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.