Java程序  |  120行  |  3.78 KB

package annotator.find;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import type.DeclaredType;
import type.Type;

/**
 * @author dbro
 *
 */
public class NewInsertion extends TypedInsertion {
  private final static Pattern qualifiers = Pattern.compile("(?:\\w++\\.)*+");

  /**
   * If true, the type will be qualified with the name of the superclass.
   */
  protected boolean qualifyType;

  /**
   * Construct a NewInsertion.
   * <p>
   * If "new" already exists in the initializer, then pass a
   * {@link DeclaredType} thats name is the empty String. This will only
   * insert an annotation on the existing type.
   * <p>
   * To insert the annotation along with "new" and the type (for example,
   * {@code @Anno new Type[] \{...\}}), set the name to the type to insert.
   * This can be done either before calling this constructor, or by modifying
   * the return value of {@link #getType()}.
   *
   * @param type the type to use when inserting the receiver
   * @param criteria where to insert the text
   * @param innerTypeInsertions the inner types to go on this receiver
   */
  public NewInsertion(Type type, Criteria criteria,
      List<Insertion> innerTypeInsertions) {
    super(type, criteria, innerTypeInsertions);
    annotationsOnly = false;
    qualifyType = false;
  }

  /** {@inheritDoc} */
  @Override
  protected String getText(boolean comments, boolean abbreviate) {
    if (annotationsOnly || type.getKind() != Type.Kind.ARRAY) {
      StringBuilder b = new StringBuilder();
      List<String> annotations = type.getAnnotations();
      if (annotations.isEmpty()) { return ""; }
      for (String a : annotations) {
        b.append(' ').append(a);  // initial space removed below
      }
      return new AnnotationInsertion(b.substring(1), getCriteria(),
          getSeparateLine()).getText(comments, abbreviate);
    } else {
      DeclaredType baseType = getBaseType();
      boolean commentAnnotation = (comments && baseType.getName().isEmpty());
      String result = typeToString(type, commentAnnotation, abbreviate);
      if (!baseType.getName().isEmpty()) {
        // First, temporarily strip off any qualifiers.
        Matcher matcher = qualifiers.matcher(result);
        String prefix = "";
        if (matcher.find() && matcher.start() == 0) {
          prefix = result.substring(0, matcher.end());
          result = result.substring(matcher.end());
        }
        // If the variable name preceded the array brackets in the
        // source, extract it from the result.
        if (qualifyType) {
          for (DeclaredType t = baseType; t != null; t = t.getInnerType()) {
            result += t.getName() + ".";
          }
        }
        // Finally, prepend extracted qualifiers.
        result = prefix + result;
      }
      result = "new " + result;
      if (comments) {
        result = "/*>>> " + result + " */";
      }
      return result;
    }
  }

  /**
   * If {@code true}, qualify {@code type} with the name of the superclass.
   * This will only happen if a "new" is inserted.
   */
  public void setQualifyType(boolean qualifyType) {
    this.qualifyType = qualifyType;
  }

  /** {@inheritDoc} */
  @Override
  protected boolean addLeadingSpace(boolean gotSeparateLine, int pos,
      char precedingChar) {
    if ((precedingChar == '.' || precedingChar == '(')
        && getBaseType().getName().isEmpty()) {
      // If only the annotation is being inserted then don't insert a
      // space if it's immediately after a '.' or '('
      return false;
    }
    return super.addLeadingSpace(gotSeparateLine, pos, precedingChar);
  }

  /** {@inheritDoc} */
  @Override
  protected boolean addTrailingSpace(boolean gotSeparateLine) {
    return true;
  }

  /** {@inheritDoc} */
  @Override
  public Kind getKind() {
    return Kind.NEW;
  }
}