blob: 536d798483d8a69d9c74ed0046005ec9a0b6503c [file] [log] [blame]
The Android Open Source Project88b60792009-03-03 19:28:42 -08001/*
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
17import org.clearsilver.HDF;
18import org.clearsilver.CS;
19
20import java.util.Comparator;
21
22public 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
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
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
57 static String chooseKind(boolean isFinal, boolean isStatic)
58 {
59 if (isStatic && isFinal) {
60 return "constant";
61 } else {
62 return "field";
63 }
64 }
65
66 public TypeInfo type()
67 {
68 return mType;
69 }
70
71 public boolean isConstant()
72 {
73 return isStatic() && isFinal();
74 }
75
76 public TagInfo[] firstSentenceTags()
77 {
78 return comment().briefTags();
79 }
80
81 public TagInfo[] inlineTags()
82 {
83 return comment().tags();
84 }
85
86 public Object constantValue()
87 {
88 return mConstantValue;
89 }
90
91 public String constantLiteralValue()
92 {
93 return constantLiteralValue(mConstantValue);
94 }
95
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
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
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
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 + ".final", isFinal() ? "final" : "");
227 data.setValue(base + ".static", isStatic() ? "static" : "");
228 if (isPublic()) {
229 data.setValue(base + ".scope", "public");
230 }
231 else if (isProtected()) {
232 data.setValue(base + ".scope", "protected");
233 }
234 else if (isPackagePrivate()) {
235 data.setValue(base + ".scope", "");
236 }
237 else if (isPrivate()) {
238 data.setValue(base + ".scope", "private");
239 }
240 Object val = mConstantValue;
241 if (val != null) {
242 String dec = null;
243 String hex = null;
244 String str = null;
245
246 if (val instanceof Boolean) {
247 str = ((Boolean)val).toString();
248 }
249 else if (val instanceof Byte) {
250 dec = String.format("%d", val);
251 hex = String.format("0x%02x", val);
252 }
253 else if (val instanceof Character) {
254 dec = String.format("\'%c\'", val);
255 hex = String.format("0x%04x", val);
256 }
257 else if (val instanceof Double) {
258 str = ((Double)val).toString();
259 }
260 else if (val instanceof Float) {
261 str = ((Float)val).toString();
262 }
263 else if (val instanceof Integer) {
264 dec = String.format("%d", val);
265 hex = String.format("0x%08x", val);
266 }
267 else if (val instanceof Long) {
268 dec = String.format("%d", val);
269 hex = String.format("0x%016x", val);
270 }
271 else if (val instanceof Short) {
272 dec = String.format("%d", val);
273 hex = String.format("0x%04x", val);
274 }
275 else if (val instanceof String) {
276 str = "\"" + ((String)val) + "\"";
277 }
278 else {
279 str = "";
280 }
281
282 if (dec != null && hex != null) {
283 data.setValue(base + ".constantValue.dec", DroidDoc.escape(dec));
284 data.setValue(base + ".constantValue.hex", DroidDoc.escape(hex));
285 }
286 else {
287 data.setValue(base + ".constantValue.str", DroidDoc.escape(str));
288 data.setValue(base + ".constantValue.isString", "1");
289 }
290 }
291 }
292
293 public boolean isExecutable()
294 {
295 return false;
296 }
297
298 public boolean isTransient()
299 {
300 return mIsTransient;
301 }
302
303 public boolean isVolatile()
304 {
305 return mIsVolatile;
306 }
307
308 boolean mIsTransient;
309 boolean mIsVolatile;
310 boolean mDeprecatedKnown;
311 boolean mIsDeprecated;
312 TypeInfo mType;
313 Object mConstantValue;
314}
315