1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  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. package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode;
  18. import java.util.Vector;
  19. import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool;
  20. import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo;
  21. /**
  22. * Utilities mostly to manipulate methods and access flags.
  23. *
  24. */
  25. public class Utils {
  26. /** public access flag */
  27. public static final short ACC_PUBLIC = 1;
  28. /** private access flag */
  29. public static final short ACC_PRIVATE = 2;
  30. /** protected access flag */
  31. public static final short ACC_PROTECTED = 4;
  32. /** static access flag */
  33. public static final short ACC_STATIC = 8;
  34. /** final access flag */
  35. public static final short ACC_FINAL = 16;
  36. /** super access flag */
  37. public static final short ACC_SUPER = 32;
  38. /** synchronized access flag */
  39. public static final short ACC_SYNCHRONIZED = 32;
  40. /** volatile access flag */
  41. public static final short ACC_VOLATILE = 64;
  42. /** transient access flag */
  43. public static final short ACC_TRANSIENT = 128;
  44. /** native access flag */
  45. public static final short ACC_NATIVE = 256;
  46. /** interface access flag */
  47. public static final short ACC_INTERFACE = 512;
  48. /** abstract access flag */
  49. public static final short ACC_ABSTRACT = 1024;
  50. /** strict access flag */
  51. public static final short ACC_STRICT = 2048;
  52. /** private constructor */
  53. private Utils() {
  54. }
  55. /**
  56. * return an UTF8 value from the pool located a a specific index.
  57. * @param pool the constant pool to look at
  58. * @param index index of the UTF8 value in the constant pool
  59. * @return the value of the string if it exists
  60. * @throws ClassCastException if the index is not an UTF8 constant.
  61. */
  62. public static String getUTF8Value(ConstantPool pool, int index) {
  63. return ((Utf8CPInfo) pool.getEntry(index)).getValue();
  64. }
  65. /**
  66. * parse all parameters from a descritor into fields of java name.
  67. * @param descriptor of a method.
  68. * @return the parameter list of a given method descriptor. Each string
  69. * represent a java object with its fully qualified classname or the
  70. * primitive name such as int, long, ...
  71. */
  72. public static String[] getMethodParams(String descriptor) {
  73. int i = 0;
  74. if (descriptor.charAt(i) != '(') {
  75. throw new IllegalArgumentException("Method descriptor should start with a '('");
  76. }
  77. Vector params = new Vector();
  78. StringBuffer param = new StringBuffer();
  79. i++;
  80. while ((i = descriptor2java(descriptor, i, param)) < descriptor.length()) {
  81. params.add(param.substring(0));
  82. param = new StringBuffer();
  83. if (descriptor.charAt(i) == ')') {
  84. i++;
  85. break;
  86. }
  87. }
  88. String[] array = new String[params.size()];
  89. params.copyInto(array);
  90. return array;
  91. }
  92. /**
  93. * return the object type of a return type.
  94. * @param descriptor
  95. * @return get the return type objet of a given descriptor
  96. */
  97. public static String getMethodReturnType(String descriptor) {
  98. int pos = descriptor.indexOf(')');
  99. StringBuffer rettype = new StringBuffer();
  100. descriptor2java(descriptor, pos + 1, rettype);
  101. return rettype.toString();
  102. }
  103. /**
  104. * Parse a single descriptor symbol and returns it java equivalent.
  105. * @param descriptor the descriptor symbol.
  106. * @param i the index to look at the symbol in the descriptor string
  107. * @param sb the stringbuffer to return the java equivalent of the symbol
  108. * @return the index after the descriptor symbol
  109. */
  110. public static int descriptor2java(String descriptor, int i, StringBuffer sb) {
  111. // get the dimension
  112. StringBuffer dim = new StringBuffer();
  113. for (; descriptor.charAt(i) == '['; i++) {
  114. dim.append("[]");
  115. }
  116. // now get the type
  117. switch (descriptor.charAt(i)) {
  118. case 'B':
  119. sb.append("byte");
  120. break;
  121. case 'C':
  122. sb.append("char");
  123. break;
  124. case 'D':
  125. sb.append("double");
  126. break;
  127. case 'F':
  128. sb.append("float");
  129. break;
  130. case 'I':
  131. sb.append("int");
  132. break;
  133. case 'J':
  134. sb.append("long");
  135. break;
  136. case 'S':
  137. sb.append("short");
  138. break;
  139. case 'Z':
  140. sb.append("boolean");
  141. break;
  142. case 'V':
  143. sb.append("void");
  144. break;
  145. case 'L':
  146. // it is a class
  147. int pos = descriptor.indexOf(';', i + 1);
  148. String classname = descriptor.substring(i + 1, pos).replace('/', '.');
  149. sb.append(classname);
  150. i = pos;
  151. break;
  152. default:
  153. //@todo, yeah this happens because I got things like:
  154. // ()Ljava/lang/Object; and it will return and ) will be here
  155. // think about it.
  156. //ooooops should never happen
  157. //throw new IllegalArgumentException("Invalid descriptor
  158. // symbol: '" + i + "' in '" + descriptor + "'");
  159. }
  160. sb.append(dim.toString());
  161. return ++i;
  162. }
  163. /**
  164. * check for abstract access
  165. * @param access_flags access flags
  166. */
  167. public static boolean isAbstract(int access_flags) {
  168. return (access_flags & ACC_ABSTRACT) != 0;
  169. }
  170. /**
  171. * check for public access
  172. * @param access_flags access flags
  173. */
  174. public static boolean isPublic(int access_flags) {
  175. return (access_flags & ACC_PUBLIC) != 0;
  176. }
  177. /**
  178. * check for a static access
  179. * @param access_flags access flags
  180. */
  181. public static boolean isStatic(int access_flags) {
  182. return (access_flags & ACC_STATIC) != 0;
  183. }
  184. /**
  185. * check for native access
  186. * @param access_flags access flags
  187. */
  188. public static boolean isNative(int access_flags) {
  189. return (access_flags & ACC_NATIVE) != 0;
  190. }
  191. /**
  192. * check for class access
  193. * @param access_flags access flags
  194. */
  195. public static boolean isClass(int access_flags) {
  196. return !isInterface(access_flags);
  197. }
  198. /**
  199. * check for strict access
  200. * @param access_flags access flags
  201. */
  202. public static boolean isStrict(int access_flags) {
  203. return (access_flags & ACC_STRICT) != 0;
  204. }
  205. /**
  206. * check for interface access
  207. * @param access_flags access flags
  208. */
  209. public static boolean isInterface(int access_flags) {
  210. return (access_flags & ACC_INTERFACE) != 0;
  211. }
  212. /**
  213. * check for private access
  214. * @param access_flags access flags
  215. */
  216. public static boolean isPrivate(int access_flags) {
  217. return (access_flags & ACC_PRIVATE) != 0;
  218. }
  219. /**
  220. * check for transient flag
  221. * @param access_flags access flags
  222. */
  223. public static boolean isTransient(int access_flags) {
  224. return (access_flags & ACC_TRANSIENT) != 0;
  225. }
  226. /**
  227. * check for volatile flag
  228. * @param access_flags access flags
  229. */
  230. public static boolean isVolatile(int access_flags) {
  231. return (access_flags & ACC_VOLATILE) != 0;
  232. }
  233. /**
  234. * check for super flag
  235. * @param access_flags access flag
  236. */
  237. public static boolean isSuper(int access_flags) {
  238. return (access_flags & ACC_SUPER) != 0;
  239. }
  240. /**
  241. * check for protected flag
  242. * @param access_flags access flags
  243. */
  244. public static boolean isProtected(int access_flags) {
  245. return (access_flags & ACC_PROTECTED) != 0;
  246. }
  247. /**
  248. * chck for final flag
  249. * @param access_flags access flags
  250. */
  251. public static boolean isFinal(int access_flags) {
  252. return (access_flags & ACC_FINAL) != 0;
  253. }
  254. /**
  255. * check for synchronized flag
  256. * @param access_flags access flags
  257. */
  258. public static boolean isSynchronized(int access_flags) {
  259. return (access_flags & ACC_SYNCHRONIZED) != 0;
  260. }
  261. /**
  262. * return the method access flag as java modifiers
  263. * @param access_flags access flags
  264. * @return the access flags as modifier strings
  265. */
  266. public static String getMethodAccess(int access_flags) {
  267. StringBuffer sb = new StringBuffer();
  268. if (isPublic(access_flags)) {
  269. sb.append("public ");
  270. } else if (isPrivate(access_flags)) {
  271. sb.append("private ");
  272. } else if (isProtected(access_flags)) {
  273. sb.append("protected ");
  274. }
  275. if (isFinal(access_flags)) {
  276. sb.append("final ");
  277. }
  278. if (isStatic(access_flags)) {
  279. sb.append("static ");
  280. }
  281. if (isSynchronized(access_flags)) {
  282. sb.append("synchronized ");
  283. }
  284. if (isNative(access_flags)) {
  285. sb.append("native ");
  286. }
  287. if (isAbstract(access_flags)) {
  288. sb.append("abstract ");
  289. }
  290. return sb.toString().trim();
  291. }
  292. /**
  293. * return the field access flag as java modifiers
  294. * @param access_flags access flags
  295. * @return the access flags as modifier strings
  296. */
  297. public static String getFieldAccess(int access_flags) {
  298. StringBuffer sb = new StringBuffer();
  299. if (isPublic(access_flags)) {
  300. sb.append("public ");
  301. } else if (isPrivate(access_flags)) {
  302. sb.append("private ");
  303. } else if (isProtected(access_flags)) {
  304. sb.append("protected ");
  305. }
  306. if (isFinal(access_flags)) {
  307. sb.append("final ");
  308. }
  309. if (isStatic(access_flags)) {
  310. sb.append("static ");
  311. }
  312. if (isVolatile(access_flags)) {
  313. sb.append("volatile ");
  314. }
  315. if (isTransient(access_flags)) {
  316. sb.append("transient ");
  317. }
  318. return sb.toString().trim();
  319. }
  320. /**
  321. * return the class access flag as java modifiers
  322. * @param access_flags access flags
  323. * @return the access flags as modifier strings
  324. */
  325. public static String getClassAccess(int access_flags) {
  326. StringBuffer sb = new StringBuffer();
  327. if (isPublic(access_flags)) {
  328. sb.append("public ");
  329. } else if (isProtected(access_flags)) {
  330. sb.append("protected ");
  331. } else if (isPrivate(access_flags)) {
  332. sb.append("private ");
  333. }
  334. if (isFinal(access_flags)) {
  335. sb.append("final ");
  336. }
  337. if (isSuper(access_flags)) {
  338. sb.append("/*super*/ ");
  339. }
  340. if (isInterface(access_flags)) {
  341. sb.append("interface ");
  342. }
  343. if (isAbstract(access_flags)) {
  344. sb.append("abstract ");
  345. }
  346. if (isClass(access_flags)) {
  347. sb.append("class ");
  348. }
  349. return sb.toString().trim();
  350. }
  351. }