blob: 5c31488c1c98ed9691b88368a3526804fdfe742d [file] [log] [blame]
package annotator.find;
import java.util.List;
import type.DeclaredType;
/**
* An insertion for a method receiver. This supports inserting an
* annotation on an existing receiver and creating a new (annotated)
* receiver if none are present.
*/
public class ReceiverInsertion extends TypedInsertion {
/**
* If true a comma will be added at the end of the insertion (only if also
* inserting the receiver).
*/
private boolean addComma;
/**
* If true, {@code this} will be qualified with the name of the
* superclass.
*/
private boolean qualifyThis;
/**
* Construct a ReceiverInsertion.
* <p>
* If the receiver parameter already exists in the method declaration, then
* pass a DeclaredType thats name is the empty String. This will only insert
* an annotation on the existing receiver.
* <p>
* To insert the annotation and the receiver (for example,
* {@code @Anno Type this}) the name should be set to the type to insert.
* This can either be done before calling this constructor, or by modifying
* the return value of {@link #getType()}.
* <p>
* A comma will not be added to the end of the receiver. In the case that
* there is a parameter following the inserted receiver pass {@code true} to
* {@link #setAddComma(boolean)} to add a comma to the end of the receiver.
*
* @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 ReceiverInsertion(DeclaredType type, Criteria criteria, List<Insertion> innerTypeInsertions) {
super(type, criteria, innerTypeInsertions);
addComma = false;
qualifyThis = false;
}
/**
* If {@code true} a comma will be added at the end of the receiver.
* This will only happen if a receiver is inserted (see
* {@link #ReceiverInsertion(DeclaredType, Criteria, List)} for a description of
* when a receiver is inserted). This is useful if the method already has
* one or more parameters.
*/
public void setAddComma(boolean addComma) {
this.addComma = addComma;
}
/**
* If {@code true}, qualify {@code this} with the name of the superclass.
* This will only happen if a receiver is inserted (see
* {@link #ReceiverInsertion(DeclaredType, Criteria, List)}
* for a description of when a receiver is inserted). This is useful
* for inner class constructors.
*/
public void setQualifyType(boolean qualifyThis) {
this.qualifyThis = qualifyThis;
}
/** {@inheritDoc} */
@Override
protected String getText(boolean comments, boolean abbreviate) {
if (annotationsOnly) {
StringBuilder b = new StringBuilder();
List<String> annotations = type.getAnnotations();
if (annotations.isEmpty()) { return ""; }
for (String a : annotations) {
b.append(a);
b.append(' ');
}
return new AnnotationInsertion(b.toString(), 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()) {
result += " ";
if (qualifyThis) {
for (DeclaredType t = baseType; t != null;
t = t.getInnerType()) {
result += t.getName() + ".";
}
}
result += "this";
if (addComma) {
result += ",";
}
if (comments) {
result = "/*>>> " + result + " */";
}
}
return result;
}
}
/** {@inheritDoc} */
@Override
protected boolean addLeadingSpace(boolean gotSeparateLine, int pos,
char precedingChar) {
if (precedingChar == '.' && getBaseType().getName().isEmpty()) {
// If only the annotation is being inserted then don't insert a
// space if it's immediately after a '.'
return false;
}
return super.addLeadingSpace(gotSeparateLine, pos, precedingChar);
}
/** {@inheritDoc} */
@Override
protected boolean addTrailingSpace(boolean gotSeparateLine) {
// If the type is not already in the source and the receiver is the only
// parameter, don't add a trailing space.
if (!getBaseType().getName().isEmpty() && !addComma) {
return false;
}
return super.addTrailingSpace(gotSeparateLine);
}
/** {@inheritDoc} */
@Override
public Kind getKind() {
return Kind.RECEIVER;
}
}