blob: 1c975e4da068fffc2b39024a990cf2cf5a585982 [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());
Jesse Wilson289d80e2009-07-21 14:02:14 -0700226 data.setValue(base + ".since", getSince());
The Android Open Source Project88b60792009-03-03 19:28:42 -0800227 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 public boolean isExecutable()
295 {
296 return false;
297 }
298
299 public boolean isTransient()
300 {
301 return mIsTransient;
302 }
303
304 public boolean isVolatile()
305 {
306 return mIsVolatile;
307 }
308
309 boolean mIsTransient;
310 boolean mIsVolatile;
311 boolean mDeprecatedKnown;
312 boolean mIsDeprecated;
313 TypeInfo mType;
314 Object mConstantValue;
315}
316