1 package annotations.field; 2 3 /*>>> 4 import org.checkerframework.checker.nullness.qual.*; 5 */ 6 7 import java.util.HashMap; 8 import java.util.Map; 9 10 import com.google.common.escape.CharEscaperBuilder; 11 import com.google.common.escape.Escaper; 12 13 /** 14 * A <code>BasicAFT</code> represents a primitive or {@link String} annotation 15 * field type. Get one using {@link #forType(Class)}. 16 */ 17 // should be an enum except they can't be generic and can't extend a class 18 public final class BasicAFT extends ScalarAFT { 19 static final Escaper charEscaper = 20 new CharEscaperBuilder() 21 .addEscape('\b', "\\b") 22 .addEscape('\f', "\\f") 23 .addEscape('\n', "\\n") 24 .addEscape('\r', "\\r") 25 .addEscape('\t', "\\t") 26 .addEscape('\"', "\\\"") 27 .addEscape('\\', "\\\\") 28 .addEscape('\'', "\\'") 29 .toEscaper(); 30 31 /** 32 * The Java type backing this annotation field type. 33 */ 34 public final Class<?> type; 35 BasicAFT(Class<?> type)36 private BasicAFT(Class<?> type) { 37 this.type = type; 38 } 39 40 /** 41 * Returns the <code>BasicAFT</code> for <code>type</code>, which 42 * should be primitive (e.g., int.class) or String. Returns null if 43 * <code>type</code> is not appropriate for a basic annotation field 44 * type. 45 */ forType(Class<?> type)46 public static BasicAFT forType(Class<?> type) { 47 return bafts.get(type); 48 } 49 50 /** 51 * Maps from {@link #type} to <code>BasicAFT</code>. 52 * Contains every BasicAFT. 53 */ 54 // Disgusting reason for being public; need to fix. 55 public static final Map<Class<?>, BasicAFT> bafts; 56 57 static { 58 Map<Class<?>, BasicAFT> tempBafts = 59 new HashMap<Class<?>, BasicAFT>(9); tempBafts.put(byte.class, new BasicAFT(byte.class))60 tempBafts.put(byte.class, new BasicAFT(byte.class)); tempBafts.put(short.class, new BasicAFT(short.class))61 tempBafts.put(short.class, new BasicAFT(short.class)); tempBafts.put(int.class, new BasicAFT(int.class))62 tempBafts.put(int.class, new BasicAFT(int.class)); tempBafts.put(long.class, new BasicAFT(long.class))63 tempBafts.put(long.class, new BasicAFT(long.class)); tempBafts.put(float.class, new BasicAFT(float.class))64 tempBafts.put(float.class, new BasicAFT(float.class)); tempBafts.put(double.class, new BasicAFT(double.class))65 tempBafts.put(double.class, new BasicAFT(double.class)); tempBafts.put(char.class, new BasicAFT(char.class))66 tempBafts.put(char.class, new BasicAFT(char.class)); tempBafts.put(boolean.class, new BasicAFT(boolean.class))67 tempBafts.put(boolean.class, new BasicAFT(boolean.class)); tempBafts.put(String.class, new BasicAFT(String.class))68 tempBafts.put(String.class, new BasicAFT(String.class)); 69 // bafts = Collections2.<Class<?>, BasicAFT>unmodifiableKeyedSet(tempBafts); 70 // bafts = bafts2; 71 bafts = tempBafts; 72 } 73 74 /** 75 * {@inheritDoc} 76 */ 77 @Override isValidValue(Object o)78 public boolean isValidValue(Object o) { 79 return ( (type == byte.class && o instanceof Byte) 80 || (type == short.class && o instanceof Short) 81 || (type == int.class && o instanceof Integer) 82 || (type == long.class && o instanceof Long) 83 || (type == float.class && o instanceof Float) 84 || (type == double.class && o instanceof Double) 85 || (type == char.class && o instanceof Character) 86 || (type == boolean.class && o instanceof Boolean) 87 || (type == String.class && o instanceof String)); 88 } 89 90 /** 91 * {@inheritDoc} 92 */ 93 @Override toString()94 public String toString() { 95 if (type == String.class) { 96 return "String"; 97 } else { 98 return type.getName(); 99 } 100 } 101 102 /** 103 * {@inheritDoc} 104 */ 105 @Override format(Object o)106 public String format(Object o) { 107 return type != String.class ? o.toString() 108 : "\"" + charEscaper.escape((String) o) + "\""; 109 } 110 111 @Override accept(AFTVisitor<R, T> v, T arg)112 public <R, T> R accept(AFTVisitor<R, T> v, T arg) { 113 return v.visitBasicAFT(this, arg); 114 } 115 } 116