You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DescendingVisitor.java 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. package org.aspectj.apache.bcel.verifier;
  2. /* ====================================================================
  3. * The Apache Software License, Version 1.1
  4. *
  5. * Copyright (c) 2001 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (https://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Apache" and "Apache Software Foundation" and
  28. * "Apache BCEL" must not be used to endorse or promote products
  29. * derived from this software without prior written permission. For
  30. * written permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * "Apache BCEL", nor may "Apache" appear in their name, without
  34. * prior written permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation. For more
  52. * information on the Apache Software Foundation, please see
  53. * <https://www.apache.org/>.
  54. */
  55. import java.util.Stack;
  56. import org.aspectj.apache.bcel.classfile.AnnotationDefault;
  57. import org.aspectj.apache.bcel.classfile.Attribute;
  58. import org.aspectj.apache.bcel.classfile.AttributeUtils;
  59. import org.aspectj.apache.bcel.classfile.BootstrapMethods;
  60. import org.aspectj.apache.bcel.classfile.ClassVisitor;
  61. import org.aspectj.apache.bcel.classfile.Code;
  62. import org.aspectj.apache.bcel.classfile.CodeException;
  63. import org.aspectj.apache.bcel.classfile.Constant;
  64. import org.aspectj.apache.bcel.classfile.ConstantClass;
  65. import org.aspectj.apache.bcel.classfile.ConstantDouble;
  66. import org.aspectj.apache.bcel.classfile.ConstantDynamic;
  67. import org.aspectj.apache.bcel.classfile.ConstantFieldref;
  68. import org.aspectj.apache.bcel.classfile.ConstantFloat;
  69. import org.aspectj.apache.bcel.classfile.ConstantInteger;
  70. import org.aspectj.apache.bcel.classfile.ConstantInterfaceMethodref;
  71. import org.aspectj.apache.bcel.classfile.ConstantInvokeDynamic;
  72. import org.aspectj.apache.bcel.classfile.ConstantLong;
  73. import org.aspectj.apache.bcel.classfile.ConstantMethodHandle;
  74. import org.aspectj.apache.bcel.classfile.ConstantMethodType;
  75. import org.aspectj.apache.bcel.classfile.ConstantMethodref;
  76. import org.aspectj.apache.bcel.classfile.ConstantModule;
  77. import org.aspectj.apache.bcel.classfile.ConstantNameAndType;
  78. import org.aspectj.apache.bcel.classfile.ConstantPackage;
  79. import org.aspectj.apache.bcel.classfile.ConstantPool;
  80. import org.aspectj.apache.bcel.classfile.ConstantString;
  81. import org.aspectj.apache.bcel.classfile.ConstantUtf8;
  82. import org.aspectj.apache.bcel.classfile.ConstantValue;
  83. import org.aspectj.apache.bcel.classfile.Deprecated;
  84. import org.aspectj.apache.bcel.classfile.EnclosingMethod;
  85. import org.aspectj.apache.bcel.classfile.ExceptionTable;
  86. import org.aspectj.apache.bcel.classfile.Field;
  87. import org.aspectj.apache.bcel.classfile.InnerClass;
  88. import org.aspectj.apache.bcel.classfile.InnerClasses;
  89. import org.aspectj.apache.bcel.classfile.JavaClass;
  90. import org.aspectj.apache.bcel.classfile.LineNumber;
  91. import org.aspectj.apache.bcel.classfile.LineNumberTable;
  92. import org.aspectj.apache.bcel.classfile.LocalVariable;
  93. import org.aspectj.apache.bcel.classfile.LocalVariableTable;
  94. import org.aspectj.apache.bcel.classfile.LocalVariableTypeTable;
  95. import org.aspectj.apache.bcel.classfile.Method;
  96. import org.aspectj.apache.bcel.classfile.MethodParameters;
  97. import org.aspectj.apache.bcel.classfile.Module;
  98. import org.aspectj.apache.bcel.classfile.ModuleMainClass;
  99. import org.aspectj.apache.bcel.classfile.ModulePackages;
  100. import org.aspectj.apache.bcel.classfile.NestHost;
  101. import org.aspectj.apache.bcel.classfile.NestMembers;
  102. import org.aspectj.apache.bcel.classfile.Signature;
  103. import org.aspectj.apache.bcel.classfile.SourceFile;
  104. import org.aspectj.apache.bcel.classfile.StackMap;
  105. import org.aspectj.apache.bcel.classfile.StackMapEntry;
  106. import org.aspectj.apache.bcel.classfile.Synthetic;
  107. import org.aspectj.apache.bcel.classfile.Unknown;
  108. import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos;
  109. import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos;
  110. import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos;
  111. import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos;
  112. import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos;
  113. import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos;
  114. /**
  115. * Traverses a JavaClass with another Visitor object 'piggy-backed' that is
  116. * applied to all components of a JavaClass object. I.e. this class supplies the
  117. * traversal strategy, other classes can make use of it.
  118. *
  119. * @version $Id: DescendingVisitor.java,v 1.4 2009/09/15 19:40:22 aclement Exp $
  120. * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  121. */
  122. public class DescendingVisitor implements ClassVisitor {
  123. private JavaClass clazz;
  124. private ClassVisitor visitor;
  125. private Stack<Object> stack = new Stack<Object>();
  126. /**
  127. * @return container of current entitity, i.e., predecessor during traversal
  128. */
  129. public Object predecessor() {
  130. return predecessor(0);
  131. }
  132. /**
  133. * @param level
  134. * nesting level, i.e., 0 returns the direct predecessor
  135. * @return container of current entitity, i.e., predecessor during traversal
  136. */
  137. public Object predecessor(int level) {
  138. int size = stack.size();
  139. if ((size < 2) || (level < 0))
  140. return null;
  141. else
  142. return stack.elementAt(size - (level + 2)); // size - 1 == current
  143. }
  144. /**
  145. * @return current object
  146. */
  147. public Object current() {
  148. return stack.peek();
  149. }
  150. /**
  151. * @param clazz
  152. * Class to traverse
  153. * @param visitor
  154. * visitor object to apply to all components
  155. */
  156. public DescendingVisitor(JavaClass clazz, ClassVisitor visitor) {
  157. this.clazz = clazz;
  158. this.visitor = visitor;
  159. }
  160. /**
  161. * Start traversal.
  162. */
  163. public void visit() {
  164. clazz.accept(this);
  165. }
  166. @Override
  167. public void visitJavaClass(JavaClass clazz) {
  168. stack.push(clazz);
  169. clazz.accept(visitor);
  170. Field[] fields = clazz.getFields();
  171. for (int i = 0; i < fields.length; i++)
  172. fields[i].accept(this);
  173. Method[] methods = clazz.getMethods();
  174. for (int i = 0; i < methods.length; i++)
  175. methods[i].accept(this);
  176. AttributeUtils.accept(clazz.getAttributes(), visitor);
  177. // clazz.getAttributes().accept(this);
  178. clazz.getConstantPool().accept(this);
  179. stack.pop();
  180. }
  181. @Override
  182. public void visitField(Field field) {
  183. stack.push(field);
  184. field.accept(visitor);
  185. AttributeUtils.accept(field.getAttributes(), visitor);
  186. // field.getAttributes().accept(this);
  187. stack.pop();
  188. }
  189. @Override
  190. public void visitConstantValue(ConstantValue cv) {
  191. stack.push(cv);
  192. cv.accept(visitor);
  193. stack.pop();
  194. }
  195. @Override
  196. public void visitMethod(Method method) {
  197. stack.push(method);
  198. method.accept(visitor);
  199. AttributeUtils.accept(method.getAttributes(), visitor);
  200. stack.pop();
  201. }
  202. @Override
  203. public void visitExceptionTable(ExceptionTable table) {
  204. stack.push(table);
  205. table.accept(visitor);
  206. stack.pop();
  207. }
  208. @Override
  209. public void visitCode(Code code) {
  210. stack.push(code);
  211. code.accept(visitor);
  212. CodeException[] table = code.getExceptionTable();
  213. for (int i = 0; i < table.length; i++)
  214. table[i].accept(this);
  215. Attribute[] attributes = code.getAttributes();
  216. for (int i = 0; i < attributes.length; i++)
  217. attributes[i].accept(this);
  218. stack.pop();
  219. }
  220. @Override
  221. public void visitCodeException(CodeException ce) {
  222. stack.push(ce);
  223. ce.accept(visitor);
  224. stack.pop();
  225. }
  226. @Override
  227. public void visitLineNumberTable(LineNumberTable table) {
  228. stack.push(table);
  229. table.accept(visitor);
  230. LineNumber[] numbers = table.getLineNumberTable();
  231. for (int i = 0; i < numbers.length; i++)
  232. numbers[i].accept(this);
  233. stack.pop();
  234. }
  235. @Override
  236. public void visitLineNumber(LineNumber number) {
  237. stack.push(number);
  238. number.accept(visitor);
  239. stack.pop();
  240. }
  241. @Override
  242. public void visitLocalVariableTable(LocalVariableTable table) {
  243. stack.push(table);
  244. table.accept(visitor);
  245. LocalVariable[] vars = table.getLocalVariableTable();
  246. for (int i = 0; i < vars.length; i++)
  247. vars[i].accept(this);
  248. stack.pop();
  249. }
  250. @Override
  251. public void visitStackMap(StackMap table) {
  252. stack.push(table);
  253. table.accept(visitor);
  254. StackMapEntry[] vars = table.getStackMap();
  255. for (int i = 0; i < vars.length; i++)
  256. vars[i].accept(this);
  257. stack.pop();
  258. }
  259. @Override
  260. public void visitStackMapEntry(StackMapEntry var) {
  261. stack.push(var);
  262. var.accept(visitor);
  263. stack.pop();
  264. }
  265. @Override
  266. public void visitLocalVariable(LocalVariable var) {
  267. stack.push(var);
  268. var.accept(visitor);
  269. stack.pop();
  270. }
  271. @Override
  272. public void visitConstantPool(ConstantPool cp) {
  273. stack.push(cp);
  274. cp.accept(visitor);
  275. Constant[] constants = cp.getConstantPool();
  276. for (int i = 1; i < constants.length; i++) {
  277. if (constants[i] != null)
  278. constants[i].accept(this);
  279. }
  280. stack.pop();
  281. }
  282. @Override
  283. public void visitConstantClass(ConstantClass constant) {
  284. stack.push(constant);
  285. constant.accept(visitor);
  286. stack.pop();
  287. }
  288. @Override
  289. public void visitConstantDouble(ConstantDouble constant) {
  290. stack.push(constant);
  291. constant.accept(visitor);
  292. stack.pop();
  293. }
  294. @Override
  295. public void visitConstantFieldref(ConstantFieldref constant) {
  296. stack.push(constant);
  297. constant.accept(visitor);
  298. stack.pop();
  299. }
  300. @Override
  301. public void visitConstantFloat(ConstantFloat constant) {
  302. stack.push(constant);
  303. constant.accept(visitor);
  304. stack.pop();
  305. }
  306. @Override
  307. public void visitConstantInteger(ConstantInteger constant) {
  308. stack.push(constant);
  309. constant.accept(visitor);
  310. stack.pop();
  311. }
  312. @Override
  313. public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref constant) {
  314. stack.push(constant);
  315. constant.accept(visitor);
  316. stack.pop();
  317. }
  318. @Override
  319. public void visitConstantLong(ConstantLong constant) {
  320. stack.push(constant);
  321. constant.accept(visitor);
  322. stack.pop();
  323. }
  324. @Override
  325. public void visitConstantMethodref(ConstantMethodref constant) {
  326. stack.push(constant);
  327. constant.accept(visitor);
  328. stack.pop();
  329. }
  330. @Override
  331. public void visitConstantMethodHandle(ConstantMethodHandle constant) {
  332. throw new IllegalStateException("nyi");
  333. }
  334. @Override
  335. public void visitConstantMethodType(ConstantMethodType obj) {
  336. throw new IllegalStateException("nyi");
  337. }
  338. @Override
  339. public void visitConstantInvokeDynamic(ConstantInvokeDynamic constant) {
  340. stack.push(constant);
  341. constant.accept(visitor);
  342. stack.pop();
  343. }
  344. @Override
  345. public void visitConstantDynamic(ConstantDynamic obj) {
  346. stack.push(obj);
  347. obj.accept(visitor);
  348. stack.pop();
  349. }
  350. @Override
  351. public void visitBootstrapMethods(BootstrapMethods obj) {
  352. throw new IllegalStateException("nyi");
  353. }
  354. @Override
  355. public void visitConstantNameAndType(ConstantNameAndType constant) {
  356. stack.push(constant);
  357. constant.accept(visitor);
  358. stack.pop();
  359. }
  360. @Override
  361. public void visitConstantString(ConstantString constant) {
  362. stack.push(constant);
  363. constant.accept(visitor);
  364. stack.pop();
  365. }
  366. @Override
  367. public void visitConstantModule(ConstantModule constant) {
  368. stack.push(constant);
  369. constant.accept(visitor);
  370. stack.pop();
  371. }
  372. @Override
  373. public void visitConstantPackage(ConstantPackage constant) {
  374. stack.push(constant);
  375. constant.accept(visitor);
  376. stack.pop();
  377. }
  378. @Override
  379. public void visitConstantUtf8(ConstantUtf8 constant) {
  380. stack.push(constant);
  381. constant.accept(visitor);
  382. stack.pop();
  383. }
  384. @Override
  385. public void visitInnerClasses(InnerClasses ic) {
  386. stack.push(ic);
  387. ic.accept(visitor);
  388. InnerClass[] ics = ic.getInnerClasses();
  389. for (int i = 0; i < ics.length; i++)
  390. ics[i].accept(this);
  391. stack.pop();
  392. }
  393. @Override
  394. public void visitInnerClass(InnerClass inner) {
  395. stack.push(inner);
  396. inner.accept(visitor);
  397. stack.pop();
  398. }
  399. @Override
  400. public void visitDeprecated(Deprecated attribute) {
  401. stack.push(attribute);
  402. attribute.accept(visitor);
  403. stack.pop();
  404. }
  405. @Override
  406. public void visitSignature(Signature attribute) {
  407. stack.push(attribute);
  408. attribute.accept(visitor);
  409. stack.pop();
  410. }
  411. // J5SUPPORT:
  412. @Override
  413. public void visitEnclosingMethod(EnclosingMethod attribute) {
  414. stack.push(attribute);
  415. attribute.accept(visitor);
  416. stack.pop();
  417. }
  418. @Override
  419. public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos attribute) {
  420. stack.push(attribute);
  421. attribute.accept(visitor);
  422. stack.pop();
  423. }
  424. @Override
  425. public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos attribute) {
  426. stack.push(attribute);
  427. attribute.accept(visitor);
  428. stack.pop();
  429. }
  430. @Override
  431. public void visitRuntimeVisibleParameterAnnotations(RuntimeVisParamAnnos attribute) {
  432. stack.push(attribute);
  433. attribute.accept(visitor);
  434. stack.pop();
  435. }
  436. @Override
  437. public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisParamAnnos attribute) {
  438. stack.push(attribute);
  439. attribute.accept(visitor);
  440. stack.pop();
  441. }
  442. @Override
  443. public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos attribute) {
  444. stack.push(attribute);
  445. attribute.accept(visitor);
  446. stack.pop();
  447. }
  448. @Override
  449. public void visitMethodParameters(MethodParameters attribute) {
  450. stack.push(attribute);
  451. attribute.accept(visitor);
  452. stack.pop();
  453. }
  454. @Override
  455. public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos attribute) {
  456. stack.push(attribute);
  457. attribute.accept(visitor);
  458. stack.pop();
  459. }
  460. @Override
  461. public void visitAnnotationDefault(AnnotationDefault attribute) {
  462. stack.push(attribute);
  463. attribute.accept(visitor);
  464. stack.pop();
  465. }
  466. @Override
  467. public void visitLocalVariableTypeTable(LocalVariableTypeTable table) {
  468. stack.push(table);
  469. table.accept(visitor);
  470. LocalVariable[] vars = table.getLocalVariableTypeTable();
  471. for (int i = 0; i < vars.length; i++)
  472. vars[i].accept(this);
  473. stack.pop();
  474. }
  475. @Override
  476. public void visitSourceFile(SourceFile attribute) {
  477. stack.push(attribute);
  478. attribute.accept(visitor);
  479. stack.pop();
  480. }
  481. @Override
  482. public void visitSynthetic(Synthetic attribute) {
  483. stack.push(attribute);
  484. attribute.accept(visitor);
  485. stack.pop();
  486. }
  487. @Override
  488. public void visitUnknown(Unknown attribute) {
  489. stack.push(attribute);
  490. attribute.accept(visitor);
  491. stack.pop();
  492. }
  493. @Override
  494. public void visitModule(Module attribute) {
  495. stack.push(attribute);
  496. attribute.accept(visitor);
  497. stack.pop();
  498. }
  499. @Override
  500. public void visitModulePackages(ModulePackages attribute) {
  501. stack.push(attribute);
  502. attribute.accept(visitor);
  503. stack.pop();
  504. }
  505. @Override
  506. public void visitModuleMainClass(ModuleMainClass attribute) {
  507. stack.push(attribute);
  508. attribute.accept(visitor);
  509. stack.pop();
  510. }
  511. @Override
  512. public void visitNestHost(NestHost attribute) {
  513. stack.push(attribute);
  514. attribute.accept(visitor);
  515. stack.pop();
  516. }
  517. @Override
  518. public void visitNestMembers(NestMembers attribute) {
  519. stack.push(attribute);
  520. attribute.accept(visitor);
  521. stack.pop();
  522. }
  523. }