1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.clearsilver.HDF; 18 import org.clearsilver.CS; 19 20 import java.util.Comparator; 21 22 public class FieldInfo extends MemberInfo 23 { 24 public static final Comparator<FieldInfo> comparator = new Comparator<FieldInfo>() { 25 public int compare(FieldInfo a, FieldInfo b) { 26 return a.name().compareTo(b.name()); 27 } 28 }; 29 FieldInfo(String name, ClassInfo containingClass, ClassInfo realContainingClass, boolean isPublic, boolean isProtected, boolean isPackagePrivate, boolean isPrivate, boolean isFinal, boolean isStatic, boolean isTransient, boolean isVolatile, boolean isSynthetic, TypeInfo type, String rawCommentText, Object constantValue, SourcePositionInfo position, AnnotationInstanceInfo[] annotations)30 public FieldInfo(String name, ClassInfo containingClass, ClassInfo realContainingClass, 31 boolean isPublic, boolean isProtected, 32 boolean isPackagePrivate, boolean isPrivate, 33 boolean isFinal, boolean isStatic, boolean isTransient, boolean isVolatile, 34 boolean isSynthetic, TypeInfo type, String rawCommentText, 35 Object constantValue, 36 SourcePositionInfo position, 37 AnnotationInstanceInfo[] annotations) 38 { 39 super(rawCommentText, name, null, containingClass, realContainingClass, 40 isPublic, isProtected, isPackagePrivate, isPrivate, 41 isFinal, isStatic, isSynthetic, chooseKind(isFinal, isStatic), position, 42 annotations); 43 mIsTransient = isTransient; 44 mIsVolatile = isVolatile; 45 mType = type; 46 mConstantValue = constantValue; 47 } 48 cloneForClass(ClassInfo newContainingClass)49 public FieldInfo cloneForClass(ClassInfo newContainingClass) { 50 return new FieldInfo(name(), newContainingClass, realContainingClass(), 51 isPublic(), isProtected(), isPackagePrivate(), 52 isPrivate(), isFinal(), isStatic(), isTransient(), isVolatile(), 53 isSynthetic(), mType, getRawCommentText(), mConstantValue, position(), 54 annotations()); 55 } 56 chooseKind(boolean isFinal, boolean isStatic)57 static String chooseKind(boolean isFinal, boolean isStatic) 58 { 59 if (isStatic && isFinal) { 60 return "constant"; 61 } else { 62 return "field"; 63 } 64 } 65 type()66 public TypeInfo type() 67 { 68 return mType; 69 } 70 isConstant()71 public boolean isConstant() 72 { 73 return isStatic() && isFinal(); 74 } 75 firstSentenceTags()76 public TagInfo[] firstSentenceTags() 77 { 78 return comment().briefTags(); 79 } 80 inlineTags()81 public TagInfo[] inlineTags() 82 { 83 return comment().tags(); 84 } 85 constantValue()86 public Object constantValue() 87 { 88 return mConstantValue; 89 } 90 constantLiteralValue()91 public String constantLiteralValue() 92 { 93 return constantLiteralValue(mConstantValue); 94 } 95 isDeprecated()96 public boolean isDeprecated() { 97 boolean deprecated = false; 98 if (!mDeprecatedKnown) { 99 boolean commentDeprecated = (comment().deprecatedTags().length > 0); 100 boolean annotationDeprecated = false; 101 for (AnnotationInstanceInfo annotation : annotations()) { 102 if (annotation.type().qualifiedName().equals("java.lang.Deprecated")) { 103 annotationDeprecated = true; 104 break; 105 } 106 } 107 108 if (commentDeprecated != annotationDeprecated) { 109 Errors.error(Errors.DEPRECATION_MISMATCH, position(), 110 "Field " + mContainingClass.qualifiedName() + "." + name() 111 + ": @Deprecated annotation and @deprecated comment do not match"); 112 } 113 114 mIsDeprecated = commentDeprecated | annotationDeprecated; 115 mDeprecatedKnown = true; 116 } 117 return mIsDeprecated; 118 } 119 constantLiteralValue(Object val)120 public static String constantLiteralValue(Object val) 121 { 122 String str = null; 123 if (val != null) { 124 if (val instanceof Boolean 125 || val instanceof Byte 126 || val instanceof Short 127 || val instanceof Integer) 128 { 129 str = val.toString(); 130 } 131 //catch all special values 132 else if (val instanceof Double){ 133 Double dbl = (Double) val; 134 if (dbl.toString().equals("Infinity")){ 135 str = "(1.0 / 0.0)"; 136 } else if (dbl.toString().equals("-Infinity")) { 137 str = "(-1.0 / 0.0)"; 138 } else if (dbl.isNaN()) { 139 str = "(0.0 / 0.0)"; 140 } else { 141 str = dbl.toString(); 142 } 143 } 144 else if (val instanceof Long) { 145 str = val.toString() + "L"; 146 } 147 else if (val instanceof Float) { 148 Float fl = (Float) val; 149 if (fl.toString().equals("Infinity")) { 150 str = "(1.0f / 0.0f)"; 151 } else if (fl.toString().equals("-Infinity")) { 152 str = "(-1.0f / 0.0f)"; 153 } else if (fl.isNaN()) { 154 str = "(0.0f / 0.0f)"; 155 } else { 156 str = val.toString() + "f"; 157 } 158 } 159 else if (val instanceof Character) { 160 str = String.format("\'\\u%04x\'", val); 161 } 162 else if (val instanceof String) { 163 str = "\"" + javaEscapeString((String)val) + "\""; 164 } 165 else { 166 str = "<<<<" +val.toString() + ">>>>"; 167 } 168 } 169 if (str == null) { 170 str = "null"; 171 } 172 return str; 173 } 174 javaEscapeString(String str)175 public static String javaEscapeString(String str) { 176 String result = ""; 177 final int N = str.length(); 178 for (int i=0; i<N; i++) { 179 char c = str.charAt(i); 180 if (c == '\\') { 181 result += "\\\\"; 182 } 183 else if (c == '\t') { 184 result += "\\t"; 185 } 186 else if (c == '\b') { 187 result += "\\b"; 188 } 189 else if (c == '\r') { 190 result += "\\r"; 191 } 192 else if (c == '\n') { 193 result += "\\n"; 194 } 195 else if (c == '\f') { 196 result += "\\f"; 197 } 198 else if (c == '\'') { 199 result += "\\'"; 200 } 201 else if (c == '\"') { 202 result += "\\\""; 203 } 204 else if (c >= ' ' && c <= '~') { 205 result += c; 206 } 207 else { 208 result += String.format("\\u%04x", new Integer((int)c)); 209 } 210 } 211 return result; 212 } 213 214 makeHDF(HDF data, String base)215 public void makeHDF(HDF data, String base) 216 { 217 data.setValue(base + ".kind", kind()); 218 type().makeHDF(data, base + ".type"); 219 data.setValue(base + ".name", name()); 220 data.setValue(base + ".href", htmlPage()); 221 data.setValue(base + ".anchor", anchor()); 222 TagInfo.makeHDF(data, base + ".shortDescr", firstSentenceTags()); 223 TagInfo.makeHDF(data, base + ".descr", inlineTags()); 224 TagInfo.makeHDF(data, base + ".deprecated", comment().deprecatedTags()); 225 TagInfo.makeHDF(data, base + ".seeAlso", comment().seeTags()); 226 data.setValue(base + ".since", getSince()); 227 data.setValue(base + ".final", isFinal() ? "final" : ""); 228 data.setValue(base + ".static", isStatic() ? "static" : ""); 229 if (isPublic()) { 230 data.setValue(base + ".scope", "public"); 231 } 232 else if (isProtected()) { 233 data.setValue(base + ".scope", "protected"); 234 } 235 else if (isPackagePrivate()) { 236 data.setValue(base + ".scope", ""); 237 } 238 else if (isPrivate()) { 239 data.setValue(base + ".scope", "private"); 240 } 241 Object val = mConstantValue; 242 if (val != null) { 243 String dec = null; 244 String hex = null; 245 String str = null; 246 247 if (val instanceof Boolean) { 248 str = ((Boolean)val).toString(); 249 } 250 else if (val instanceof Byte) { 251 dec = String.format("%d", val); 252 hex = String.format("0x%02x", val); 253 } 254 else if (val instanceof Character) { 255 dec = String.format("\'%c\'", val); 256 hex = String.format("0x%04x", val); 257 } 258 else if (val instanceof Double) { 259 str = ((Double)val).toString(); 260 } 261 else if (val instanceof Float) { 262 str = ((Float)val).toString(); 263 } 264 else if (val instanceof Integer) { 265 dec = String.format("%d", val); 266 hex = String.format("0x%08x", val); 267 } 268 else if (val instanceof Long) { 269 dec = String.format("%d", val); 270 hex = String.format("0x%016x", val); 271 } 272 else if (val instanceof Short) { 273 dec = String.format("%d", val); 274 hex = String.format("0x%04x", val); 275 } 276 else if (val instanceof String) { 277 str = "\"" + ((String)val) + "\""; 278 } 279 else { 280 str = ""; 281 } 282 283 if (dec != null && hex != null) { 284 data.setValue(base + ".constantValue.dec", DroidDoc.escape(dec)); 285 data.setValue(base + ".constantValue.hex", DroidDoc.escape(hex)); 286 } 287 else { 288 data.setValue(base + ".constantValue.str", DroidDoc.escape(str)); 289 data.setValue(base + ".constantValue.isString", "1"); 290 } 291 } 292 } 293 294 @Override isExecutable()295 public boolean isExecutable() 296 { 297 return false; 298 } 299 isTransient()300 public boolean isTransient() 301 { 302 return mIsTransient; 303 } 304 isVolatile()305 public boolean isVolatile() 306 { 307 return mIsVolatile; 308 } 309 310 boolean mIsTransient; 311 boolean mIsVolatile; 312 boolean mDeprecatedKnown; 313 boolean mIsDeprecated; 314 TypeInfo mType; 315 Object mConstantValue; 316 } 317 318