package annotations.field; /*>>> import org.checkerframework.checker.nullness.qual.*; */ import java.util.HashMap; import java.util.Map; import com.google.common.escape.CharEscaperBuilder; import com.google.common.escape.Escaper; /** * A <code>BasicAFT</code> represents a primitive or {@link String} annotation * field type. Get one using {@link #forType(Class)}. */ // should be an enum except they can't be generic and can't extend a class public final class BasicAFT extends ScalarAFT { static final Escaper charEscaper = new CharEscaperBuilder() .addEscape('\b', "\\b") .addEscape('\f', "\\f") .addEscape('\n', "\\n") .addEscape('\r', "\\r") .addEscape('\t', "\\t") .addEscape('\"', "\\\"") .addEscape('\\', "\\\\") .addEscape('\'', "\\'") .toEscaper(); /** * The Java type backing this annotation field type. */ public final Class<?> type; private BasicAFT(Class<?> type) { this.type = type; } /** * Returns the <code>BasicAFT</code> for <code>type</code>, which * should be primitive (e.g., int.class) or String. Returns null if * <code>type</code> is not appropriate for a basic annotation field * type. */ public static BasicAFT forType(Class<?> type) { return bafts.get(type); } /** * Maps from {@link #type} to <code>BasicAFT</code>. * Contains every BasicAFT. */ // Disgusting reason for being public; need to fix. public static final Map<Class<?>, BasicAFT> bafts; static { Map<Class<?>, BasicAFT> tempBafts = new HashMap<Class<?>, BasicAFT>(9); tempBafts.put(byte.class, new BasicAFT(byte.class)); tempBafts.put(short.class, new BasicAFT(short.class)); tempBafts.put(int.class, new BasicAFT(int.class)); tempBafts.put(long.class, new BasicAFT(long.class)); tempBafts.put(float.class, new BasicAFT(float.class)); tempBafts.put(double.class, new BasicAFT(double.class)); tempBafts.put(char.class, new BasicAFT(char.class)); tempBafts.put(boolean.class, new BasicAFT(boolean.class)); tempBafts.put(String.class, new BasicAFT(String.class)); // bafts = Collections2.<Class<?>, BasicAFT>unmodifiableKeyedSet(tempBafts); // bafts = bafts2; bafts = tempBafts; } /** * {@inheritDoc} */ @Override public boolean isValidValue(Object o) { return ( (type == byte.class && o instanceof Byte) || (type == short.class && o instanceof Short) || (type == int.class && o instanceof Integer) || (type == long.class && o instanceof Long) || (type == float.class && o instanceof Float) || (type == double.class && o instanceof Double) || (type == char.class && o instanceof Character) || (type == boolean.class && o instanceof Boolean) || (type == String.class && o instanceof String)); } /** * {@inheritDoc} */ @Override public String toString() { if (type == String.class) { return "String"; } else { return type.getName(); } } /** * {@inheritDoc} */ @Override public String format(Object o) { return type != String.class ? o.toString() : "\"" + charEscaper.escape((String) o) + "\""; } @Override public <R, T> R accept(AFTVisitor<R, T> v, T arg) { return v.visitBasicAFT(this, arg); } }