framework.src.org.checkerframework.qualframework.poly.format.PrettyQualifiedTypeFormatter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of checker Show documentation
Show all versions of checker Show documentation
The Checker Framework enhances Java’s type system to
make it more powerful and useful. This lets software developers
detect and prevent errors in their Java programs.
The Checker Framework includes compiler plug-ins ("checkers")
that find bugs or verify their absence. It also permits you to
write your own compiler plug-ins.
package org.checkerframework.qualframework.poly.format;
import org.checkerframework.framework.type.AnnotatedTypeFormatter;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.framework.type.DefaultAnnotatedTypeFormatter;
import org.checkerframework.framework.util.AnnotationFormatter;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.qualframework.base.TypeMirrorConverter;
import org.checkerframework.qualframework.base.format.DefaultQualifiedTypeFormatter;
import org.checkerframework.qualframework.poly.PolyQual;
import org.checkerframework.qualframework.poly.QualParams;
import org.checkerframework.qualframework.qual.QualifierKey;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import java.util.List;
import java.util.Set;
/**
* PrettyQualifiedTypeFormatter formats QualifiedTypeMirrors with QualParams qualifiers
* into Strings.
*
* PrettyQualifiedTypeFormatter prints the primary qualifier of a QualParams before a
* declared type's name, and the map of qualifier parameters after the declared type's name.
*/
public class PrettyQualifiedTypeFormatter extends DefaultQualifiedTypeFormatter, PrettyQualParamsFormatter> {
public PrettyQualifiedTypeFormatter(
TypeMirrorConverter> converter,
Set invisibleQualifiers,
boolean useOldFormat,
boolean defaultPrintInvisibleQualifiers) {
super(new PrettyQualParamsFormatter(invisibleQualifiers), converter, useOldFormat, defaultPrintInvisibleQualifiers);
}
@Override
protected AnnotatedTypeFormatter createAnnotatedTypeFormatter(AnnotationFormatter annotationFormatter) {
return new QualParamsAnnoTypeFormatter(converter, qualFormatter,
annotationFormatter, useOldFormat, defaultPrintInvisibleQualifiers);
}
/**
* QualParamsAnnoTypeFormatter is an DefaultAnnotatedTypeFormatter that overrides the visitDeclared
* method in order to pretty print QualParams.
*/
private static class QualParamsAnnoTypeFormatter extends DefaultAnnotatedTypeFormatter {
protected QualParamsAnnoTypeFormatter(
TypeMirrorConverter> converter,
QualParamsFormatter formatter,
org.checkerframework.framework.util.AnnotationFormatter annoFormatter,
boolean printVerboseGenerics,
boolean defaultPrintInvisibleQualifier) {
super(new FormattingVisitor(converter, annoFormatter, formatter, printVerboseGenerics, defaultPrintInvisibleQualifier));
}
protected static class FormattingVisitor extends DefaultAnnotatedTypeFormatter.FormattingVisitor {
private final TypeMirrorConverter> converter;
private final QualParamsFormatter formatter;
public FormattingVisitor(
TypeMirrorConverter> converter,
org.checkerframework.framework.util.AnnotationFormatter annoFormatter,
QualParamsFormatter formatter,
boolean printVerboseGenerics,
boolean defaultInvisiblesSetting) {
super(annoFormatter, printVerboseGenerics, defaultInvisiblesSetting);
this.converter = converter;
this.formatter = formatter;
}
/**
* visitDeclared changes the supertype behavior to print primary qualifiers before the class name
* and the qualifier parameters inside double chevrons after the class name.
*/
@Override
public String visitDeclared(AnnotatedDeclaredType type, Set visiting) {
StringBuilder sb = new StringBuilder();
if (type.isDeclaration()) {
sb.append("/*DECL*/ ");
}
final Element typeElt = type.getUnderlyingType().asElement();
String smpl = typeElt.getSimpleName().toString();
if (smpl.isEmpty()) {
// For anonymous classes smpl is empty - toString
// of the element is more useful.
smpl = typeElt.toString();
}
// Print out primary qualifiers first
for (AnnotationMirror anno : type.getAnnotations()) {
// Print out any qualifier parameters (without printing primary).
if (AnnotationUtils.areSameByClass(anno, QualifierKey.class)) {
PolyQual qual = converter.getQualifier(anno).getPrimary();
String result = formatter.format(qual, currentPrintInvisibleSetting);
if (result != null) {
sb.append(result);
sb.append(" ");
}
}
}
// Print out type name
sb.append(smpl);
// Finally print out qualifier parameters
boolean first = true;
for (AnnotationMirror anno : type.getAnnotations()) {
if (AnnotationUtils.areSameByClass(anno, QualifierKey.class)) {
QualParams qual = converter.getQualifier(anno);
String result = formatter.format(qual, false, currentPrintInvisibleSetting);
if (result != null) {
if (first) {
first = false;
} else {
sb.append(" ");
}
sb.append(result);
}
}
}
final List typeArgs = type.getTypeArguments();
if (!typeArgs.isEmpty()) {
sb.append("<");
boolean isFirst = true;
for (AnnotatedTypeMirror typeArg : typeArgs) {
if (!isFirst) sb.append(", ");
sb.append(visit(typeArg, visiting));
isFirst = false;
}
sb.append(">");
}
return sb.toString();
}
}
}
}