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.

BcelTypeMunger.java 86KB

21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
21 years ago
12 years ago
21 years ago
21 years ago
14 years ago
21 years ago
14 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
12 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
14 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
12 years ago
14 years ago
14 years ago
13 years ago
12 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
15 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
14 years ago
15 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
14 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
21 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
18 years ago
18 years ago
18 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * Alexandre Vasseur @AspectJ ITDs
  12. * ******************************************************************/
  13. package org.aspectj.weaver.bcel;
  14. import java.lang.reflect.Modifier;
  15. import java.util.ArrayList;
  16. import java.util.HashMap;
  17. import java.util.HashSet;
  18. import java.util.Iterator;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.Set;
  22. import org.aspectj.apache.bcel.Constants;
  23. import org.aspectj.apache.bcel.classfile.ClassFormatException;
  24. import org.aspectj.apache.bcel.classfile.ConstantPool;
  25. import org.aspectj.apache.bcel.classfile.Signature;
  26. import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
  27. import org.aspectj.apache.bcel.generic.FieldGen;
  28. import org.aspectj.apache.bcel.generic.InstructionBranch;
  29. import org.aspectj.apache.bcel.generic.InstructionConstants;
  30. import org.aspectj.apache.bcel.generic.InstructionFactory;
  31. import org.aspectj.apache.bcel.generic.InstructionHandle;
  32. import org.aspectj.apache.bcel.generic.InstructionList;
  33. import org.aspectj.apache.bcel.generic.InvokeInstruction;
  34. import org.aspectj.apache.bcel.generic.Type;
  35. import org.aspectj.asm.AsmManager;
  36. import org.aspectj.asm.IProgramElement;
  37. import org.aspectj.bridge.IMessage;
  38. import org.aspectj.bridge.ISourceLocation;
  39. import org.aspectj.bridge.Message;
  40. import org.aspectj.bridge.MessageUtil;
  41. import org.aspectj.bridge.WeaveMessage;
  42. import org.aspectj.bridge.context.CompilationAndWeavingContext;
  43. import org.aspectj.bridge.context.ContextToken;
  44. import org.aspectj.weaver.AjcMemberMaker;
  45. import org.aspectj.weaver.AnnotationAJ;
  46. import org.aspectj.weaver.AnnotationOnTypeMunger;
  47. import org.aspectj.weaver.BCException;
  48. import org.aspectj.weaver.ConcreteTypeMunger;
  49. import org.aspectj.weaver.Member;
  50. import org.aspectj.weaver.MemberUtils;
  51. import org.aspectj.weaver.MethodDelegateTypeMunger;
  52. import org.aspectj.weaver.NameMangler;
  53. import org.aspectj.weaver.NewConstructorTypeMunger;
  54. import org.aspectj.weaver.NewFieldTypeMunger;
  55. import org.aspectj.weaver.NewMemberClassTypeMunger;
  56. import org.aspectj.weaver.NewMethodTypeMunger;
  57. import org.aspectj.weaver.NewParentTypeMunger;
  58. import org.aspectj.weaver.PerObjectInterfaceTypeMunger;
  59. import org.aspectj.weaver.PrivilegedAccessMunger;
  60. import org.aspectj.weaver.ResolvedMember;
  61. import org.aspectj.weaver.ResolvedMemberImpl;
  62. import org.aspectj.weaver.ResolvedType;
  63. import org.aspectj.weaver.ResolvedTypeMunger;
  64. import org.aspectj.weaver.Shadow;
  65. import org.aspectj.weaver.TypeVariableReference;
  66. import org.aspectj.weaver.UnresolvedType;
  67. import org.aspectj.weaver.WeaverMessages;
  68. import org.aspectj.weaver.WeaverStateInfo;
  69. import org.aspectj.weaver.World;
  70. import org.aspectj.weaver.model.AsmRelationshipProvider;
  71. import org.aspectj.weaver.patterns.DeclareAnnotation;
  72. import org.aspectj.weaver.patterns.Pointcut;
  73. public class BcelTypeMunger extends ConcreteTypeMunger {
  74. public BcelTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) {
  75. super(munger, aspectType);
  76. }
  77. @Override
  78. public String toString() {
  79. return "(BcelTypeMunger " + getMunger() + ")";
  80. }
  81. @Override
  82. public boolean shouldOverwrite() {
  83. return false;
  84. }
  85. public boolean munge(BcelClassWeaver weaver) {
  86. ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MUNGING_WITH, this);
  87. boolean changed = false;
  88. boolean worthReporting = true;
  89. if (weaver.getWorld().isOverWeaving()) {
  90. WeaverStateInfo typeWeaverState = weaver.getLazyClassGen().getType().getWeaverState();
  91. if (typeWeaverState != null && typeWeaverState.isAspectAlreadyApplied(getAspectType())) {
  92. return false;
  93. }
  94. }
  95. if (munger.getKind() == ResolvedTypeMunger.Field) {
  96. changed = mungeNewField(weaver, (NewFieldTypeMunger) munger);
  97. } else if (munger.getKind() == ResolvedTypeMunger.Method) {
  98. changed = mungeNewMethod(weaver, (NewMethodTypeMunger) munger);
  99. } else if (munger.getKind() == ResolvedTypeMunger.InnerClass) {
  100. changed = mungeNewMemberType(weaver, (NewMemberClassTypeMunger) munger);
  101. } else if (munger.getKind() == ResolvedTypeMunger.MethodDelegate2) {
  102. changed = mungeMethodDelegate(weaver, (MethodDelegateTypeMunger) munger);
  103. } else if (munger.getKind() == ResolvedTypeMunger.FieldHost) {
  104. changed = mungeFieldHost(weaver, (MethodDelegateTypeMunger.FieldHostTypeMunger) munger);
  105. } else if (munger.getKind() == ResolvedTypeMunger.PerObjectInterface) {
  106. changed = mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger) munger);
  107. worthReporting = false;
  108. } else if (munger.getKind() == ResolvedTypeMunger.PerTypeWithinInterface) {
  109. // PTWIMPL Transform the target type (add the aspect instance field)
  110. changed = mungePerTypeWithinTransformer(weaver);
  111. worthReporting = false;
  112. } else if (munger.getKind() == ResolvedTypeMunger.PrivilegedAccess) {
  113. changed = mungePrivilegedAccess(weaver, (PrivilegedAccessMunger) munger);
  114. worthReporting = false;
  115. } else if (munger.getKind() == ResolvedTypeMunger.Constructor) {
  116. changed = mungeNewConstructor(weaver, (NewConstructorTypeMunger) munger);
  117. } else if (munger.getKind() == ResolvedTypeMunger.Parent) {
  118. changed = mungeNewParent(weaver, (NewParentTypeMunger) munger);
  119. } else if (munger.getKind() == ResolvedTypeMunger.AnnotationOnType) {
  120. changed = mungeNewAnnotationOnType(weaver, (AnnotationOnTypeMunger) munger);
  121. worthReporting = false;
  122. } else {
  123. throw new RuntimeException("unimplemented");
  124. }
  125. if (changed && munger.changesPublicSignature()) {
  126. WeaverStateInfo info = weaver.getLazyClassGen().getOrCreateWeaverStateInfo(weaver.getReweavableMode());
  127. info.addConcreteMunger(this);
  128. }
  129. if (changed && worthReporting) {
  130. ResolvedType declaringAspect = null;
  131. AsmManager model = ((BcelWorld) getWorld()).getModelAsAsmManager();
  132. if (model != null) {
  133. if (munger instanceof NewParentTypeMunger) {
  134. NewParentTypeMunger nptMunger = (NewParentTypeMunger) munger;
  135. declaringAspect = nptMunger.getDeclaringType();
  136. if (declaringAspect.isParameterizedOrGenericType()) {
  137. declaringAspect = declaringAspect.getRawType();
  138. }
  139. ResolvedType thisAspect = getAspectType();
  140. AsmRelationshipProvider.addRelationship(model, weaver.getLazyClassGen().getType(), munger, thisAspect);
  141. // Add a relationship on the actual declaring aspect too
  142. if (!thisAspect.equals(declaringAspect)) {
  143. // Might be the case the declaring aspect is generic and thisAspect is parameterizing it. In that case
  144. // record the actual parameterizations
  145. ResolvedType target = weaver.getLazyClassGen().getType();
  146. ResolvedType newParent = nptMunger.getNewParent();
  147. IProgramElement thisAspectNode = model.getHierarchy().findElementForType(thisAspect.getPackageName(),
  148. thisAspect.getClassName());
  149. Map<String, List<String>> declareParentsMap = thisAspectNode.getDeclareParentsMap();
  150. if (declareParentsMap == null) {
  151. declareParentsMap = new HashMap<>();
  152. thisAspectNode.setDeclareParentsMap(declareParentsMap);
  153. }
  154. String tname = target.getName();
  155. String pname = newParent.getName();
  156. List<String> newparents = declareParentsMap.computeIfAbsent(tname, k -> new ArrayList<>());
  157. newparents.add(pname);
  158. AsmRelationshipProvider.addRelationship(model, weaver.getLazyClassGen().getType(), munger, declaringAspect);
  159. }
  160. } else {
  161. declaringAspect = getAspectType();
  162. AsmRelationshipProvider.addRelationship(model, weaver.getLazyClassGen().getType(), munger, declaringAspect);
  163. }
  164. }
  165. }
  166. // TAG: WeavingMessage
  167. if (changed && worthReporting && munger != null && !weaver.getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
  168. String tName = weaver.getLazyClassGen().getType().getSourceLocation().getSourceFile().getName();
  169. if (tName.contains("no debug info available")) {
  170. tName = "no debug info available";
  171. } else {
  172. tName = getShortname(weaver.getLazyClassGen().getType().getSourceLocation().getSourceFile().getPath());
  173. }
  174. String fName = getShortname(getAspectType().getSourceLocation().getSourceFile().getPath());
  175. if (munger.getKind().equals(ResolvedTypeMunger.Parent)) {
  176. // This message could come out of AjLookupEnvironment.addParent
  177. // if doing parents munging at compile time only...
  178. NewParentTypeMunger parentTM = (NewParentTypeMunger) munger;
  179. if (parentTM.isMixin()) {
  180. weaver.getWorld()
  181. .getMessageHandler()
  182. .handleMessage(
  183. WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_MIXIN, new String[] {
  184. parentTM.getNewParent().getName(), fName, weaver.getLazyClassGen().getType().getName(),
  185. tName }, weaver.getLazyClassGen().getClassName(), getAspectType().getName()));
  186. } else {
  187. if (parentTM.getNewParent().isInterface()) {
  188. weaver.getWorld()
  189. .getMessageHandler()
  190. .handleMessage(
  191. WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS,
  192. new String[] { weaver.getLazyClassGen().getType().getName(), tName,
  193. parentTM.getNewParent().getName(), fName }, weaver.getLazyClassGen()
  194. .getClassName(), getAspectType().getName()));
  195. } else {
  196. weaver.getWorld()
  197. .getMessageHandler()
  198. .handleMessage(
  199. WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSEXTENDS,
  200. new String[] { weaver.getLazyClassGen().getType().getName(), tName,
  201. parentTM.getNewParent().getName(), fName }));
  202. // TAG: WeavingMessage DECLARE PARENTS: EXTENDS
  203. // reportDeclareParentsMessage(WeaveMessage.
  204. // WEAVEMESSAGE_DECLAREPARENTSEXTENDS,sourceType,parent);
  205. }
  206. }
  207. } else if (munger.getKind().equals(ResolvedTypeMunger.FieldHost)) {
  208. // hidden
  209. } else {
  210. ResolvedMember declaredSig = munger.getSignature();
  211. String fromString = fName + ":'" + declaredSig + "'";
  212. // if (declaredSig==null) declaredSig= munger.getSignature();
  213. String kindString = munger.getKind().toString().toLowerCase();
  214. if (kindString.equals("innerclass")) {
  215. kindString = "member class";
  216. fromString = fName;
  217. }
  218. weaver.getWorld()
  219. .getMessageHandler()
  220. .handleMessage(
  221. WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ITD, new String[] {
  222. weaver.getLazyClassGen().getType().getName(), tName, kindString, getAspectType().getName(),
  223. fromString }, weaver.getLazyClassGen().getClassName(), getAspectType().getName()));
  224. }
  225. }
  226. CompilationAndWeavingContext.leavingPhase(tok);
  227. return changed;
  228. }
  229. private String getShortname(String path) {
  230. int takefrom = path.lastIndexOf('/');
  231. if (takefrom == -1) {
  232. takefrom = path.lastIndexOf('\\');
  233. }
  234. return path.substring(takefrom + 1);
  235. }
  236. private boolean mungeNewAnnotationOnType(BcelClassWeaver weaver, AnnotationOnTypeMunger munger) {
  237. // FIXME asc this has already been done up front, need to do it here too?
  238. try {
  239. BcelAnnotation anno = (BcelAnnotation) munger.getNewAnnotation();
  240. weaver.getLazyClassGen().addAnnotation(anno.getBcelAnnotation());
  241. } catch (ClassCastException cce) {
  242. throw new IllegalStateException("DiagnosticsFor318237: The typemunger "+munger+" contains an annotation of type "+
  243. munger.getNewAnnotation().getClass().getName()+" when it should be a BcelAnnotation",cce);
  244. }
  245. return true;
  246. }
  247. /**
  248. * For a long time, AspectJ did not allow binary weaving of declare parents. This restriction is now lifted but could do with
  249. * more testing!
  250. */
  251. private boolean mungeNewParent(BcelClassWeaver weaver, NewParentTypeMunger typeTransformer) {
  252. LazyClassGen newParentTarget = weaver.getLazyClassGen();
  253. ResolvedType newParent = typeTransformer.getNewParent();
  254. boolean performChange = true;
  255. performChange = enforceDecpRule1_abstractMethodsImplemented(weaver, typeTransformer.getSourceLocation(), newParentTarget,
  256. newParent);
  257. performChange = enforceDecpRule2_cantExtendFinalClass(weaver, typeTransformer.getSourceLocation(), newParentTarget,
  258. newParent) && performChange;
  259. List<ResolvedMember> methods = newParent.getMethodsWithoutIterator(false, true, false);
  260. for (ResolvedMember method : methods) {
  261. if (!method.getName().equals("<init>")) {
  262. LazyMethodGen subMethod = findMatchingMethod(newParentTarget, method);
  263. // FIXME asc is this safe for all bridge methods?
  264. if (subMethod != null && !subMethod.isBridgeMethod()) {
  265. if (!(subMethod.isSynthetic() && method.isSynthetic())) {
  266. if (!(subMethod.isStatic() && subMethod.getName().startsWith("access$"))) {
  267. // ignore generated accessors
  268. performChange = enforceDecpRule3_visibilityChanges(weaver, newParent, method, subMethod)
  269. && performChange;
  270. performChange = enforceDecpRule4_compatibleReturnTypes(weaver, method, subMethod) && performChange;
  271. performChange = enforceDecpRule5_cantChangeFromStaticToNonstatic(weaver,
  272. typeTransformer.getSourceLocation(), method, subMethod)
  273. && performChange;
  274. }
  275. }
  276. }
  277. }
  278. }
  279. if (!performChange) {
  280. // A rule was violated and an error message already reported
  281. return false;
  282. }
  283. if (newParent.isClass()) {
  284. // Changing the supertype
  285. if (!attemptToModifySuperCalls(weaver, newParentTarget, newParent)) {
  286. return false;
  287. }
  288. newParentTarget.setSuperClass(newParent);
  289. } else {
  290. // Add a new interface
  291. newParentTarget.addInterface(newParent, getSourceLocation());
  292. }
  293. return true;
  294. }
  295. /**
  296. * Rule 1: For the declare parents to be allowed, the target type must override and implement inherited abstract methods (if the
  297. * type is not declared abstract)
  298. */
  299. private boolean enforceDecpRule1_abstractMethodsImplemented(BcelClassWeaver weaver, ISourceLocation mungerLoc,
  300. LazyClassGen newParentTarget, ResolvedType newParent) {
  301. // Ignore abstract classes or interfaces
  302. if (newParentTarget.isAbstract() || newParentTarget.isInterface()) {
  303. return true;
  304. }
  305. boolean ruleCheckingSucceeded = true;
  306. List<ResolvedMember> newParentMethods = newParent.getMethodsWithoutIterator(false, true, false);
  307. for (ResolvedMember newParentMethod : newParentMethods) {
  308. String newParentMethodName = newParentMethod.getName();
  309. // Ignore abstract ajc$interField prefixed methods
  310. if (newParentMethod.isAbstract() && !newParentMethodName.startsWith("ajc$interField")) {
  311. ResolvedMember discoveredImpl = null;
  312. List<ResolvedMember> targetMethods = newParentTarget.getType().getMethodsWithoutIterator(false, true, false);
  313. for (ResolvedMember targetMethod : targetMethods) {
  314. if (!targetMethod.isAbstract() && targetMethod.getName().equals(newParentMethodName)) {
  315. String newParentMethodSig = newParentMethod.getParameterSignature(); // ([TT;)
  316. String targetMethodSignature = targetMethod.getParameterSignature(); // ([Ljava/lang/Object;)
  317. // could be a match
  318. if (targetMethodSignature.equals(newParentMethodSig)) {
  319. discoveredImpl = targetMethod;
  320. } else {
  321. // Does the erasure match? In which case a bridge method will be created later to
  322. // satisfy the abstract method
  323. if (targetMethod.hasBackingGenericMember()
  324. && targetMethod.getBackingGenericMember().getParameterSignature().equals(newParentMethodSig)) {
  325. discoveredImpl = targetMethod;
  326. } else if (newParentMethod.hasBackingGenericMember()) {
  327. if (newParentMethod.getBackingGenericMember().getParameterSignature().equals(targetMethodSignature)) { // newParentMethod.getBackingGenericMember().getParameterSignature gives: (Pjava/util/List<TI;>;) targetMethodSignature= (Ljava/util/List;)
  328. discoveredImpl = targetMethod;
  329. } else if (targetMethod instanceof BcelMethod) {
  330. // BcelMethod does not have backing generic member set (need to investigate why). For now, special case here:
  331. UnresolvedType[] targetMethodGenericParameterTypes = targetMethod.getGenericParameterTypes();
  332. if (targetMethodGenericParameterTypes !=null) {
  333. StringBuilder b = new StringBuilder("(");
  334. for (UnresolvedType p: targetMethodGenericParameterTypes) {
  335. b.append(p.getSignature());
  336. }
  337. b.append(')');
  338. if (b.toString().equals(newParentMethodSig)) {
  339. discoveredImpl = targetMethod;
  340. }
  341. }
  342. }
  343. }
  344. }
  345. if (discoveredImpl != null) {
  346. break;
  347. }
  348. }
  349. }
  350. if (discoveredImpl == null) {
  351. // didnt find a valid implementation, lets check the
  352. // ITDs on this type to see if they satisfy it
  353. boolean satisfiedByITD = false;
  354. for (ConcreteTypeMunger m : newParentTarget.getType().getInterTypeMungersIncludingSupers()) {
  355. if (m.getMunger() != null && m.getMunger().getKind() == ResolvedTypeMunger.Method) {
  356. ResolvedMember sig = m.getSignature();
  357. if (!Modifier.isAbstract(sig.getModifiers())) {
  358. // If the ITD shares a type variable with some target type, we need to tailor it
  359. // for that type
  360. if (m.isTargetTypeParameterized()) {
  361. ResolvedType genericOnType = getWorld().resolve(sig.getDeclaringType()).getGenericType();
  362. ResolvedType actualOccurrence = newParent.discoverActualOccurrenceOfTypeInHierarchy(genericOnType);
  363. if (actualOccurrence == null) {
  364. // Handle the case where the ITD is onto the type targeted by the declare parents (PR478003)
  365. actualOccurrence = newParentTarget.getType().discoverActualOccurrenceOfTypeInHierarchy(genericOnType);
  366. }
  367. m = m.parameterizedFor(actualOccurrence);
  368. // possible sig change when type parameters filled in
  369. sig = m.getSignature();
  370. }
  371. if (ResolvedType.matches(
  372. AjcMemberMaker.interMethod(sig, m.getAspectType(),
  373. sig.getDeclaringType().resolve(weaver.getWorld()).isInterface()), newParentMethod)) {
  374. satisfiedByITD = true;
  375. }
  376. }
  377. } else if (m.getMunger() != null && m.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate2) {
  378. // AV - that should be enough, no need to check more
  379. satisfiedByITD = true;
  380. }
  381. }
  382. if (!satisfiedByITD) {
  383. error(weaver,
  384. "The type " + newParentTarget.getName() + " must implement the inherited abstract method "
  385. + newParentMethod.getDeclaringType() + "." + newParentMethodName
  386. + newParentMethod.getParameterSignature(), newParentTarget.getType().getSourceLocation(),
  387. new ISourceLocation[] { newParentMethod.getSourceLocation(), mungerLoc });
  388. ruleCheckingSucceeded = false;
  389. }
  390. }
  391. }
  392. }
  393. return ruleCheckingSucceeded;
  394. }
  395. /**
  396. * Rule 2. Can't extend final types
  397. */
  398. private boolean enforceDecpRule2_cantExtendFinalClass(BcelClassWeaver weaver, ISourceLocation transformerLoc,
  399. LazyClassGen targetType, ResolvedType newParent) {
  400. if (newParent.isFinal()) {
  401. error(weaver, "Cannot make type " + targetType.getName() + " extend final class " + newParent.getName(), targetType
  402. .getType().getSourceLocation(), new ISourceLocation[] { transformerLoc });
  403. return false;
  404. }
  405. return true;
  406. }
  407. /**
  408. * Rule 3. Can't narrow visibility of methods when overriding
  409. */
  410. private boolean enforceDecpRule3_visibilityChanges(BcelClassWeaver weaver, ResolvedType newParent, ResolvedMember superMethod,
  411. LazyMethodGen subMethod) {
  412. boolean cont = true;
  413. if (Modifier.isPublic(superMethod.getModifiers())) {
  414. if (subMethod.isProtected() || subMethod.isDefault() || subMethod.isPrivate()) {
  415. weaver.getWorld()
  416. .getMessageHandler()
  417. .handleMessage(
  418. MessageUtil.error("Cannot reduce the visibility of the inherited method '" + superMethod
  419. + "' from " + newParent.getName(), superMethod.getSourceLocation()));
  420. cont = false;
  421. }
  422. } else if (Modifier.isProtected(superMethod.getModifiers())) {
  423. if (subMethod.isDefault() || subMethod.isPrivate()) {
  424. weaver.getWorld()
  425. .getMessageHandler()
  426. .handleMessage(
  427. MessageUtil.error("Cannot reduce the visibility of the inherited method '" + superMethod
  428. + "' from " + newParent.getName(), superMethod.getSourceLocation()));
  429. cont = false;
  430. }
  431. } else if (superMethod.isDefault()) {
  432. if (subMethod.isPrivate()) {
  433. weaver.getWorld()
  434. .getMessageHandler()
  435. .handleMessage(
  436. MessageUtil.error("Cannot reduce the visibility of the inherited method '" + superMethod
  437. + "' from " + newParent.getName(), superMethod.getSourceLocation()));
  438. cont = false;
  439. }
  440. }
  441. return cont;
  442. }
  443. /**
  444. * Rule 4. Can't have incompatible return types
  445. */
  446. private boolean enforceDecpRule4_compatibleReturnTypes(BcelClassWeaver weaver, ResolvedMember superMethod,
  447. LazyMethodGen subMethod) {
  448. boolean cont = true;
  449. String superReturnTypeSig = superMethod.getGenericReturnType().getSignature(); // eg. Pjava/util/Collection<LFoo;>
  450. String subReturnTypeSig = subMethod.getGenericReturnTypeSignature();
  451. superReturnTypeSig = superReturnTypeSig.replace('.', '/');
  452. subReturnTypeSig = subReturnTypeSig.replace('.', '/');
  453. if (!superReturnTypeSig.equals(subReturnTypeSig)) {
  454. // Check for covariance
  455. ResolvedType subType = weaver.getWorld().resolve(subMethod.getReturnType());
  456. ResolvedType superType = weaver.getWorld().resolve(superMethod.getReturnType());
  457. if (!superType.isAssignableFrom(subType)) {
  458. weaver.getWorld()
  459. .getMessageHandler()
  460. .handleMessage(
  461. MessageUtil.error("The return type is incompatible with " + superMethod.getDeclaringType() + "."
  462. + superMethod.getName() + superMethod.getParameterSignature(),
  463. subMethod.getSourceLocation()));
  464. // this just might be a better error message...
  465. // "The return type '"+subReturnTypeSig+
  466. // "' is incompatible with the overridden method "
  467. // +superMethod.getDeclaringType()+"."+
  468. // superMethod.getName()+superMethod.getParameterSignature()+
  469. // " which returns '"+superReturnTypeSig+"'",
  470. cont = false;
  471. }
  472. }
  473. return cont;
  474. }
  475. /**
  476. * Rule5. Method overrides can't change the staticality (word?) - you can't override and make an instance method static or
  477. * override and make a static method an instance method.
  478. */
  479. private boolean enforceDecpRule5_cantChangeFromStaticToNonstatic(BcelClassWeaver weaver, ISourceLocation mungerLoc,
  480. ResolvedMember superMethod, LazyMethodGen subMethod) {
  481. boolean superMethodStatic = Modifier.isStatic(superMethod.getModifiers());
  482. if (superMethodStatic && !subMethod.isStatic()) {
  483. error(weaver, "This instance method " + subMethod.getName() + subMethod.getParameterSignature()
  484. + " cannot override the static method from " + superMethod.getDeclaringType().getName(),
  485. subMethod.getSourceLocation(), new ISourceLocation[] { mungerLoc });
  486. return false;
  487. } else if (!superMethodStatic && subMethod.isStatic()) {
  488. error(weaver, "The static method " + subMethod.getName() + subMethod.getParameterSignature()
  489. + " cannot hide the instance method from " + superMethod.getDeclaringType().getName(),
  490. subMethod.getSourceLocation(), new ISourceLocation[] { mungerLoc });
  491. return false;
  492. }
  493. return true;
  494. }
  495. public void error(BcelClassWeaver weaver, String text, ISourceLocation primaryLoc, ISourceLocation[] extraLocs) {
  496. IMessage msg = new Message(text, primaryLoc, true, extraLocs);
  497. weaver.getWorld().getMessageHandler().handleMessage(msg);
  498. }
  499. /**
  500. * Search the specified type for a particular method - do not use the return value in the comparison as it is not considered for
  501. * overriding.
  502. */
  503. private LazyMethodGen findMatchingMethod(LazyClassGen type, ResolvedMember searchMethod) {
  504. String searchName = searchMethod.getName();
  505. String searchSig = searchMethod.getParameterSignature();
  506. for (LazyMethodGen method : type.getMethodGens()) {
  507. if (method.getName().equals(searchName) && method.getParameterSignature().equals(searchSig)) {
  508. return method;
  509. }
  510. }
  511. return null;
  512. }
  513. /**
  514. * The main part of implementing declare parents extends. Modify super ctor calls to target the new type.
  515. */
  516. public boolean attemptToModifySuperCalls(BcelClassWeaver weaver, LazyClassGen newParentTarget, ResolvedType newParent) {
  517. ResolvedType currentParentType = newParentTarget.getSuperClass();
  518. if (currentParentType.getGenericType() != null) {
  519. currentParentType = currentParentType.getGenericType();
  520. }
  521. String currentParent = currentParentType.getName();
  522. if (newParent.getGenericType() != null) {
  523. newParent = newParent.getGenericType(); // target new super calls at
  524. }
  525. // the generic type if its raw or parameterized
  526. List<LazyMethodGen> mgs = newParentTarget.getMethodGens();
  527. // Look for ctors to modify
  528. for (LazyMethodGen aMethod : mgs) {
  529. if (LazyMethodGen.isConstructor(aMethod)) {
  530. InstructionList insList = aMethod.getBody();
  531. InstructionHandle handle = insList.getStart();
  532. while (handle != null) {
  533. if (handle.getInstruction().opcode == Constants.INVOKESPECIAL) {
  534. ConstantPool cpg = newParentTarget.getConstantPool();
  535. InvokeInstruction invokeSpecial = (InvokeInstruction) handle.getInstruction();
  536. if (invokeSpecial.getClassName(cpg).equals(currentParent)
  537. && invokeSpecial.getMethodName(cpg).equals("<init>")) {
  538. // System.err.println("Transforming super call '<init>" + invokeSpecial.getSignature(cpg) + "'");
  539. // 1. Check there is a ctor in the new parent with
  540. // the same signature
  541. ResolvedMember newCtor = getConstructorWithSignature(newParent, invokeSpecial.getSignature(cpg));
  542. if (newCtor == null) {
  543. // 2. Check ITDCs to see if the necessary ctor is provided that way
  544. boolean satisfiedByITDC = false;
  545. for (Iterator<ConcreteTypeMunger> ii = newParentTarget.getType()
  546. .getInterTypeMungersIncludingSupers().iterator(); ii.hasNext() && !satisfiedByITDC;) {
  547. ConcreteTypeMunger m = ii.next();
  548. if (m.getMunger() instanceof NewConstructorTypeMunger) {
  549. if (m.getSignature().getSignature().equals(invokeSpecial.getSignature(cpg))) {
  550. satisfiedByITDC = true;
  551. }
  552. }
  553. }
  554. if (!satisfiedByITDC) {
  555. String csig = createReadableCtorSig(newParent, cpg, invokeSpecial);
  556. weaver.getWorld()
  557. .getMessageHandler()
  558. .handleMessage(
  559. MessageUtil.error(
  560. "Unable to modify hierarchy for " + newParentTarget.getClassName()
  561. + " - the constructor " + csig + " is missing",
  562. this.getSourceLocation()));
  563. return false;
  564. }
  565. }
  566. int idx = cpg.addMethodref(newParent.getName(), invokeSpecial.getMethodName(cpg),
  567. invokeSpecial.getSignature(cpg));
  568. invokeSpecial.setIndex(idx);
  569. }
  570. }
  571. handle = handle.getNext();
  572. }
  573. }
  574. }
  575. return true;
  576. }
  577. /**
  578. * Creates a nice signature for the ctor, something like "(int,Integer,String)"
  579. */
  580. private String createReadableCtorSig(ResolvedType newParent, ConstantPool cpg, InvokeInstruction invokeSpecial) {
  581. StringBuffer sb = new StringBuffer();
  582. Type[] ctorArgs = invokeSpecial.getArgumentTypes(cpg);
  583. sb.append(newParent.getClassName());
  584. sb.append("(");
  585. for (int i = 0; i < ctorArgs.length; i++) {
  586. String argtype = ctorArgs[i].toString();
  587. if (argtype.lastIndexOf(".") != -1) {
  588. sb.append(argtype.substring(argtype.lastIndexOf(".") + 1));
  589. } else {
  590. sb.append(argtype);
  591. }
  592. if (i + 1 < ctorArgs.length) {
  593. sb.append(",");
  594. }
  595. }
  596. sb.append(")");
  597. return sb.toString();
  598. }
  599. private ResolvedMember getConstructorWithSignature(ResolvedType type, String searchSig) {
  600. for (ResolvedMember method : type.getDeclaredJavaMethods()) {
  601. if (MemberUtils.isConstructor(method)) {
  602. if (method.getSignature().equals(searchSig)) {
  603. return method;
  604. }
  605. }
  606. }
  607. return null;
  608. }
  609. private boolean mungePrivilegedAccess(BcelClassWeaver weaver, PrivilegedAccessMunger munger) {
  610. LazyClassGen gen = weaver.getLazyClassGen();
  611. ResolvedMember member = munger.getMember();
  612. ResolvedType onType = weaver.getWorld().resolve(member.getDeclaringType(), munger.getSourceLocation());
  613. if (onType.isRawType()) {
  614. onType = onType.getGenericType();
  615. }
  616. // System.out.println("munging: " + gen + " with " + member);
  617. if (onType.equals(gen.getType())) {
  618. if (member.getKind() == Member.FIELD) {
  619. // System.out.println("matched: " + gen);
  620. addFieldGetter(gen, member,
  621. AjcMemberMaker.privilegedAccessMethodForFieldGet(aspectType, member, munger.shortSyntax));
  622. addFieldSetter(gen, member,
  623. AjcMemberMaker.privilegedAccessMethodForFieldSet(aspectType, member, munger.shortSyntax));
  624. return true;
  625. } else if (member.getKind() == Member.METHOD) {
  626. addMethodDispatch(gen, member, AjcMemberMaker.privilegedAccessMethodForMethod(aspectType, member));
  627. return true;
  628. } else if (member.getKind() == Member.CONSTRUCTOR) {
  629. for (LazyMethodGen m : gen.getMethodGens()) {
  630. if (m.getMemberView() != null && m.getMemberView().getKind() == Member.CONSTRUCTOR) {
  631. // m.getMemberView().equals(member)) {
  632. m.forcePublic();
  633. // return true;
  634. }
  635. }
  636. return true;
  637. // throw new BCException("no match for " + member + " in " +
  638. // gen);
  639. } else if (member.getKind() == Member.STATIC_INITIALIZATION) {
  640. gen.forcePublic();
  641. return true;
  642. } else {
  643. throw new RuntimeException("unimplemented");
  644. }
  645. }
  646. return false;
  647. }
  648. private void addFieldGetter(LazyClassGen gen, ResolvedMember field, ResolvedMember accessMethod) {
  649. LazyMethodGen mg = makeMethodGen(gen, accessMethod);
  650. InstructionList il = new InstructionList();
  651. InstructionFactory fact = gen.getFactory();
  652. if (Modifier.isStatic(field.getModifiers())) {
  653. il.append(fact.createFieldAccess(gen.getClassName(), field.getName(), BcelWorld.makeBcelType(field.getType()),
  654. Constants.GETSTATIC));
  655. } else {
  656. il.append(InstructionConstants.ALOAD_0);
  657. il.append(fact.createFieldAccess(gen.getClassName(), field.getName(), BcelWorld.makeBcelType(field.getType()),
  658. Constants.GETFIELD));
  659. }
  660. il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(field.getType())));
  661. mg.getBody().insert(il);
  662. gen.addMethodGen(mg, getSignature().getSourceLocation());
  663. }
  664. private void addFieldSetter(LazyClassGen gen, ResolvedMember field, ResolvedMember accessMethod) {
  665. LazyMethodGen mg = makeMethodGen(gen, accessMethod);
  666. InstructionList il = new InstructionList();
  667. InstructionFactory fact = gen.getFactory();
  668. Type fieldType = BcelWorld.makeBcelType(field.getType());
  669. if (Modifier.isStatic(field.getModifiers())) {
  670. il.append(InstructionFactory.createLoad(fieldType, 0));
  671. il.append(fact.createFieldAccess(gen.getClassName(), field.getName(), fieldType, Constants.PUTSTATIC));
  672. } else {
  673. il.append(InstructionConstants.ALOAD_0);
  674. il.append(InstructionFactory.createLoad(fieldType, 1));
  675. il.append(fact.createFieldAccess(gen.getClassName(), field.getName(), fieldType, Constants.PUTFIELD));
  676. }
  677. il.append(InstructionFactory.createReturn(Type.VOID));
  678. mg.getBody().insert(il);
  679. gen.addMethodGen(mg, getSignature().getSourceLocation());
  680. }
  681. private void addMethodDispatch(LazyClassGen gen, ResolvedMember method, ResolvedMember accessMethod) {
  682. LazyMethodGen mg = makeMethodGen(gen, accessMethod);
  683. InstructionList il = new InstructionList();
  684. InstructionFactory fact = gen.getFactory();
  685. Type[] paramTypes = BcelWorld.makeBcelTypes(method.getParameterTypes());
  686. int pos = 0;
  687. if (!Modifier.isStatic(method.getModifiers())) {
  688. il.append(InstructionConstants.ALOAD_0);
  689. pos++;
  690. }
  691. for (Type paramType : paramTypes) {
  692. il.append(InstructionFactory.createLoad(paramType, pos));
  693. pos += paramType.getSize();
  694. }
  695. il.append(Utility.createInvoke(fact, (BcelWorld) aspectType.getWorld(), method));
  696. il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(method.getReturnType())));
  697. mg.getBody().insert(il);
  698. gen.addMethodGen(mg);
  699. }
  700. protected LazyMethodGen makeMethodGen(LazyClassGen gen, ResolvedMember member) {
  701. try {
  702. Type returnType = BcelWorld.makeBcelType(member.getReturnType());
  703. Type[] parameterTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());
  704. LazyMethodGen ret = new LazyMethodGen(member.getModifiers(), returnType,
  705. member.getName(), parameterTypes, UnresolvedType.getNames(member
  706. .getExceptions()), gen);
  707. // 43972 : Static crosscutting makes interfaces unusable for javac
  708. // ret.makeSynthetic();
  709. return ret;
  710. } catch (ClassFormatException cfe) {
  711. throw new RuntimeException("Problem with makeMethodGen for method "+member.getName()+" in type "+gen.getName()+" ret="+member.getReturnType(),cfe);
  712. }
  713. }
  714. protected FieldGen makeFieldGen(LazyClassGen gen, ResolvedMember member) {
  715. return new FieldGen(member.getModifiers(), BcelWorld.makeBcelType(member.getReturnType()), member.getName(),
  716. gen.getConstantPool());
  717. }
  718. private boolean mungePerObjectInterface(BcelClassWeaver weaver, PerObjectInterfaceTypeMunger munger) {
  719. // System.err.println("Munging perobject ["+munger+"] onto "+weaver.
  720. // getLazyClassGen().getClassName());
  721. LazyClassGen gen = weaver.getLazyClassGen();
  722. if (couldMatch(gen.getBcelObjectType(), munger.getTestPointcut())) {
  723. FieldGen fg = makeFieldGen(gen, AjcMemberMaker.perObjectField(gen.getType(), aspectType));
  724. gen.addField(fg, getSourceLocation());
  725. Type fieldType = BcelWorld.makeBcelType(aspectType);
  726. LazyMethodGen mg = new LazyMethodGen(Modifier.PUBLIC, fieldType, NameMangler.perObjectInterfaceGet(aspectType),
  727. new Type[0], new String[0], gen);
  728. InstructionList il = new InstructionList();
  729. InstructionFactory fact = gen.getFactory();
  730. il.append(InstructionConstants.ALOAD_0);
  731. il.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.GETFIELD));
  732. il.append(InstructionFactory.createReturn(fieldType));
  733. mg.getBody().insert(il);
  734. gen.addMethodGen(mg);
  735. LazyMethodGen mg1 = new LazyMethodGen(Modifier.PUBLIC, Type.VOID, NameMangler.perObjectInterfaceSet(aspectType),
  736. new Type[] { fieldType, }, new String[0], gen);
  737. InstructionList il1 = new InstructionList();
  738. il1.append(InstructionConstants.ALOAD_0);
  739. il1.append(InstructionFactory.createLoad(fieldType, 1));
  740. il1.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.PUTFIELD));
  741. il1.append(InstructionFactory.createReturn(Type.VOID));
  742. mg1.getBody().insert(il1);
  743. gen.addMethodGen(mg1);
  744. gen.addInterface(munger.getInterfaceType().resolve(weaver.getWorld()), getSourceLocation());
  745. return true;
  746. } else {
  747. return false;
  748. }
  749. }
  750. // PTWIMPL Add field to hold aspect instance and an accessor
  751. private boolean mungePerTypeWithinTransformer(BcelClassWeaver weaver) {
  752. LazyClassGen gen = weaver.getLazyClassGen();
  753. // if (couldMatch(gen.getBcelObjectType(), munger.getTestPointcut())) {
  754. // Add (to the target type) the field that will hold the aspect instance
  755. // e.g ajc$com_blah_SecurityAspect$ptwAspectInstance
  756. FieldGen fg = makeFieldGen(gen, AjcMemberMaker.perTypeWithinField(gen.getType(), aspectType));
  757. gen.addField(fg, getSourceLocation());
  758. if (!gen.getType().canBeSeenBy(aspectType) && aspectType.isPrivilegedAspect()) {
  759. gen.forcePublic();
  760. }
  761. // Add an accessor for this new field, the
  762. // ajc$<aspectname>$localAspectOf() method
  763. // e.g.
  764. // "public com_blah_SecurityAspect ajc$com_blah_SecurityAspect$localAspectOf()"
  765. Type fieldType = BcelWorld.makeBcelType(aspectType);
  766. LazyMethodGen mg = new LazyMethodGen(Modifier.PUBLIC | Modifier.STATIC, fieldType,
  767. NameMangler.perTypeWithinLocalAspectOf(aspectType), new Type[0], new String[0], gen);
  768. InstructionList il = new InstructionList();
  769. // PTWIMPL ?? Should check if it is null and throw
  770. // NoAspectBoundException
  771. InstructionFactory fact = gen.getFactory();
  772. il.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.GETSTATIC));
  773. il.append(InstructionFactory.createReturn(fieldType));
  774. mg.getBody().insert(il);
  775. gen.addMethodGen(mg);
  776. return true;
  777. // } else {
  778. // return false;
  779. // }
  780. }
  781. // ??? Why do we have this method? I thought by now we would know if it
  782. // matched or not
  783. private boolean couldMatch(BcelObjectType bcelObjectType, Pointcut pointcut) {
  784. return !bcelObjectType.isInterface();
  785. }
  786. private boolean mungeNewMemberType(BcelClassWeaver classWeaver, NewMemberClassTypeMunger munger) {
  787. World world = classWeaver.getWorld();
  788. ResolvedType onType = world.resolve(munger.getTargetType());
  789. if (onType.isRawType()) {
  790. onType = onType.getGenericType();
  791. }
  792. return onType.equals(classWeaver.getLazyClassGen().getType());
  793. }
  794. private boolean mungeNewMethod(BcelClassWeaver classWeaver, NewMethodTypeMunger munger) {
  795. World world = classWeaver.getWorld();
  796. // Resolving it will sort out the tvars
  797. ResolvedMember unMangledInterMethod = munger.getSignature().resolve(world);
  798. // do matching on the unMangled one, but actually add them to the mangled method
  799. ResolvedMember interMethodBody = munger.getDeclaredInterMethodBody(aspectType, world);
  800. ResolvedMember interMethodDispatcher = munger.getDeclaredInterMethodDispatcher(aspectType, world);
  801. ResolvedMember memberHoldingAnyAnnotations = interMethodDispatcher;
  802. LazyClassGen classGen = classWeaver.getLazyClassGen();
  803. ResolvedType onType = world.resolve(unMangledInterMethod.getDeclaringType(), munger.getSourceLocation());
  804. if (onType.isRawType()) {
  805. onType = onType.getGenericType();
  806. }
  807. // Simple checks, can't ITD on annotations or enums
  808. if (onType.isAnnotation()) {
  809. signalError(WeaverMessages.ITDM_ON_ANNOTATION_NOT_ALLOWED, classWeaver, onType);
  810. return false;
  811. }
  812. if (onType.isEnum()) {
  813. signalError(WeaverMessages.ITDM_ON_ENUM_NOT_ALLOWED, classWeaver, onType);
  814. return false;
  815. }
  816. boolean mungingInterface = classGen.isInterface();
  817. boolean onInterface = onType.isInterface();
  818. if (onInterface
  819. && classGen.getLazyMethodGen(unMangledInterMethod.getName(), unMangledInterMethod.getSignature(), true) != null) {
  820. // this is ok, we could be providing the default implementation of a
  821. // method
  822. // that the target has already declared
  823. return false;
  824. }
  825. // If we are processing the intended ITD target type (might be an interface)
  826. if (onType.equals(classGen.getType())) {
  827. ResolvedMember mangledInterMethod = AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, onInterface);
  828. LazyMethodGen newMethod = makeMethodGen(classGen, mangledInterMethod);
  829. if (mungingInterface) {
  830. // we want the modifiers of the ITD to be used for all *implementors* of the
  831. // interface, but the method itself we add to the interface must be public abstract
  832. newMethod.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT);
  833. }
  834. // pr98901
  835. // For copying the annotations across, we have to discover the real
  836. // member in the aspect which is holding them.
  837. if (classWeaver.getWorld().isInJava5Mode()) {
  838. AnnotationAJ annotationsOnRealMember[] = null;
  839. ResolvedType toLookOn = aspectType;
  840. if (aspectType.isRawType()) {
  841. toLookOn = aspectType.getGenericType();
  842. }
  843. ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn, memberHoldingAnyAnnotations, false);
  844. // 266602 - consider it missing to mean that the corresponding aspect had errors
  845. if (realMember == null) {
  846. // signalWarning("Unable to apply any annotations attached to " + munger.getSignature(), weaver);
  847. // throw new BCException("Couldn't find ITD init member '" + interMethodBody + "' on aspect " + aspectType);
  848. } else {
  849. annotationsOnRealMember = realMember.getAnnotations();
  850. }
  851. Set<ResolvedType> addedAnnotations = new HashSet<>();
  852. if (annotationsOnRealMember != null) {
  853. for (AnnotationAJ anno : annotationsOnRealMember) {
  854. AnnotationGen a = ((BcelAnnotation) anno).getBcelAnnotation();
  855. AnnotationGen ag = new AnnotationGen(a, classGen.getConstantPool(), true);
  856. newMethod.addAnnotation(new BcelAnnotation(ag, classWeaver.getWorld()));
  857. addedAnnotations.add(anno.getType());
  858. }
  859. }
  860. if (realMember != null) {
  861. copyOverParameterAnnotations(newMethod, realMember);
  862. }
  863. // the code below was originally added to cope with the case where an aspect declares an annotation on an ITD
  864. // declared within itself (an unusual situation). However, it also addresses the case where we may not find the
  865. // annotation on the real representation of the ITD. This can happen in a load-time weaving situation where
  866. // we couldn't add the annotation in time - and so here we recheck the declare annotations. Not quite ideal but
  867. // works. pr288635
  868. List<DeclareAnnotation> allDecams = world.getDeclareAnnotationOnMethods();
  869. for (DeclareAnnotation declareAnnotationMC : allDecams) {
  870. if (declareAnnotationMC.matches(unMangledInterMethod, world)) {
  871. // && newMethod.getEnclosingClass().getType() == aspectType) {
  872. AnnotationAJ annotation = declareAnnotationMC.getAnnotation();
  873. if (!addedAnnotations.contains(annotation.getType())) {
  874. newMethod.addAnnotation(annotation);
  875. }
  876. }
  877. }
  878. }
  879. // If it doesn't target an interface and there is a body (i.e. it isnt abstract)
  880. if (!onInterface && !Modifier.isAbstract(mangledInterMethod.getModifiers())) {
  881. InstructionList body = newMethod.getBody();
  882. InstructionFactory fact = classGen.getFactory();
  883. int pos = 0;
  884. if (!Modifier.isStatic(unMangledInterMethod.getModifiers())) {
  885. body.append(InstructionFactory.createThis());
  886. pos++;
  887. }
  888. Type[] paramTypes = BcelWorld.makeBcelTypes(mangledInterMethod.getParameterTypes());
  889. for (Type paramType : paramTypes) {
  890. body.append(InstructionFactory.createLoad(paramType, pos));
  891. pos += paramType.getSize();
  892. }
  893. body.append(Utility.createInvoke(fact, classWeaver.getWorld(), interMethodBody));
  894. body.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(mangledInterMethod.getReturnType())));
  895. if (classWeaver.getWorld().isInJava5Mode()) { // Don't need bridge
  896. // methods if not in
  897. // 1.5 mode.
  898. createAnyBridgeMethodsForCovariance(classWeaver, munger, unMangledInterMethod, onType, classGen, paramTypes);
  899. }
  900. } else {
  901. // ??? this is okay
  902. // if (!(mg.getBody() == null)) throw new
  903. // RuntimeException("bas");
  904. }
  905. if (world.isInJava5Mode()) {
  906. String basicSignature = mangledInterMethod.getSignature();
  907. String genericSignature = ((ResolvedMemberImpl) mangledInterMethod).getSignatureForAttribute();
  908. if (!basicSignature.equals(genericSignature)) {
  909. // Add a signature attribute to it
  910. newMethod.addAttribute(createSignatureAttribute(classGen.getConstantPool(), genericSignature));
  911. }
  912. }
  913. // XXX make sure to check that we set exceptions properly on this
  914. // guy.
  915. classWeaver.addLazyMethodGen(newMethod);
  916. classWeaver.getLazyClassGen().warnOnAddedMethod(newMethod.getMethod(), getSignature().getSourceLocation());
  917. addNeededSuperCallMethods(classWeaver, onType, munger.getSuperMethodsCalled());
  918. return true;
  919. } else if (onInterface && !Modifier.isAbstract(unMangledInterMethod.getModifiers())) {
  920. // This means the 'gen' should be the top most implementor
  921. // - if it is *not* then something went wrong after we worked
  922. // out that it was the top most implementor (see pr49657)
  923. if (!classGen.getType().isTopmostImplementor(onType)) {
  924. ResolvedType rtx = classGen.getType().getTopmostImplementor(onType);
  925. if (rtx == null) {
  926. // pr302460
  927. // null means there is something wrong with what we are looking at
  928. ResolvedType rt = classGen.getType();
  929. if (rt.isInterface()) {
  930. ISourceLocation sloc = munger.getSourceLocation();
  931. classWeaver
  932. .getWorld()
  933. .getMessageHandler()
  934. .handleMessage(
  935. MessageUtil.error(
  936. "ITD target "
  937. + rt.getName()
  938. + " is an interface but has been incorrectly determined to be the topmost implementor of "
  939. + onType.getName() + ". ITD is " + this.getSignature(), sloc));
  940. }
  941. if (!onType.isAssignableFrom(rt)) {
  942. ISourceLocation sloc = munger.getSourceLocation();
  943. classWeaver
  944. .getWorld()
  945. .getMessageHandler()
  946. .handleMessage(
  947. MessageUtil.error(
  948. "ITD target " + rt.getName() + " doesn't appear to implement " + onType.getName()
  949. + " why did we consider it the top most implementor? ITD is "
  950. + this.getSignature(), sloc));
  951. }
  952. } else if (!rtx.isExposedToWeaver()) {
  953. ISourceLocation sLoc = munger.getSourceLocation();
  954. classWeaver
  955. .getWorld()
  956. .getMessageHandler()
  957. .handleMessage(
  958. MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_NON_EXPOSED_IMPLEMENTOR, rtx,
  959. getAspectType().getName()), (sLoc == null ? getAspectType().getSourceLocation() : sLoc)));
  960. } else {
  961. // XXX what does this state mean?
  962. // We have incorrectly identified what is the top most
  963. // implementor and its not because
  964. // a type wasn't exposed to the weaver
  965. }
  966. return false;
  967. } else {
  968. ResolvedMember mangledInterMethod = AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, false);
  969. LazyMethodGen mg = makeMethodGen(classGen, mangledInterMethod);
  970. // From 98901#29 - need to copy annotations across
  971. if (classWeaver.getWorld().isInJava5Mode()) {
  972. AnnotationAJ annotationsOnRealMember[] = null;
  973. ResolvedType toLookOn = aspectType;
  974. if (aspectType.isRawType()) {
  975. toLookOn = aspectType.getGenericType();
  976. }
  977. ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn, memberHoldingAnyAnnotations, false);
  978. if (realMember == null) {
  979. throw new BCException("Couldn't find ITD holder member '" + memberHoldingAnyAnnotations + "' on aspect "
  980. + aspectType);
  981. }
  982. annotationsOnRealMember = realMember.getAnnotations();
  983. if (annotationsOnRealMember != null) {
  984. for (AnnotationAJ annotationX : annotationsOnRealMember) {
  985. AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
  986. AnnotationGen ag = new AnnotationGen(a, classWeaver.getLazyClassGen().getConstantPool(), true);
  987. mg.addAnnotation(new BcelAnnotation(ag, classWeaver.getWorld()));
  988. }
  989. }
  990. copyOverParameterAnnotations(mg, realMember);
  991. }
  992. if (mungingInterface) {
  993. // we want the modifiers of the ITD to be used for all
  994. // *implementors* of the
  995. // interface, but the method itself we add to the interface
  996. // must be public abstract
  997. mg.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT);
  998. }
  999. Type[] paramTypes = BcelWorld.makeBcelTypes(mangledInterMethod.getParameterTypes());
  1000. Type returnType = BcelWorld.makeBcelType(mangledInterMethod.getReturnType());
  1001. InstructionList body = mg.getBody();
  1002. InstructionFactory fact = classGen.getFactory();
  1003. int pos = 0;
  1004. if (!Modifier.isStatic(mangledInterMethod.getModifiers())) {
  1005. body.append(InstructionFactory.createThis());
  1006. pos++;
  1007. }
  1008. for (Type paramType : paramTypes) {
  1009. body.append(InstructionFactory.createLoad(paramType, pos));
  1010. pos += paramType.getSize();
  1011. }
  1012. body.append(Utility.createInvoke(fact, classWeaver.getWorld(), interMethodBody));
  1013. Type t = BcelWorld.makeBcelType(interMethodBody.getReturnType());
  1014. if (!t.equals(returnType)) {
  1015. body.append(fact.createCast(t, returnType));
  1016. }
  1017. body.append(InstructionFactory.createReturn(returnType));
  1018. mg.definingType = onType;
  1019. if (world.isInJava5Mode()) {
  1020. String basicSignature = mangledInterMethod.getSignature();
  1021. String genericSignature = ((ResolvedMemberImpl) mangledInterMethod).getSignatureForAttribute();
  1022. if (!basicSignature.equals(genericSignature)) {
  1023. // Add a signature attribute to it
  1024. mg.addAttribute(createSignatureAttribute(classGen.getConstantPool(), genericSignature));
  1025. }
  1026. }
  1027. classWeaver.addOrReplaceLazyMethodGen(mg);
  1028. addNeededSuperCallMethods(classWeaver, onType, munger.getSuperMethodsCalled());
  1029. // Work out if we need a bridge method for the new method added to the topmostimplementor.
  1030. // Check if the munger being processed is a parameterized form of the original munger
  1031. createBridgeIfNecessary(classWeaver, munger, unMangledInterMethod, classGen);
  1032. return true;
  1033. }
  1034. } else {
  1035. return false;
  1036. }
  1037. }
  1038. private void createBridgeIfNecessary(BcelClassWeaver classWeaver, NewMethodTypeMunger munger,
  1039. ResolvedMember unMangledInterMethod, LazyClassGen classGen) {
  1040. if (munger.getDeclaredSignature() != null) {
  1041. boolean needsbridging = false;
  1042. ResolvedMember mungerSignature = munger.getSignature();
  1043. ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null,
  1044. mungerSignature.getDeclaringType().resolve(getWorld()), false, munger.getTypeVariableAliases());
  1045. if (!toBridgeTo.getReturnType().getErasureSignature().equals(mungerSignature.getReturnType().getErasureSignature())) {
  1046. needsbridging = true;
  1047. }
  1048. UnresolvedType[] originalParams = toBridgeTo.getParameterTypes();
  1049. UnresolvedType[] newParams = mungerSignature.getParameterTypes();
  1050. for (int ii = 0; ii < originalParams.length; ii++) {
  1051. if (!originalParams[ii].getErasureSignature().equals(newParams[ii].getErasureSignature())) {
  1052. needsbridging = true;
  1053. }
  1054. }
  1055. if (needsbridging) {
  1056. createBridge(classWeaver, unMangledInterMethod, classGen, toBridgeTo);
  1057. }
  1058. }
  1059. }
  1060. private void copyOverParameterAnnotations(LazyMethodGen receiverMethod, ResolvedMember donorMethod) {
  1061. AnnotationAJ[][] pAnnos = donorMethod.getParameterAnnotations();
  1062. if (pAnnos != null) {
  1063. int offset = receiverMethod.isStatic() ? 0 : 1;
  1064. int param = 0;
  1065. for (int i = offset; i < pAnnos.length; i++) {
  1066. AnnotationAJ[] annosOnParam = pAnnos[i];
  1067. if (annosOnParam != null) {
  1068. for (AnnotationAJ anno : annosOnParam) {
  1069. receiverMethod.addParameterAnnotation(param, anno);
  1070. }
  1071. }
  1072. param++;
  1073. }
  1074. }
  1075. }
  1076. private void createBridge(BcelClassWeaver weaver, ResolvedMember unMangledInterMethod, LazyClassGen classGen,
  1077. ResolvedMember toBridgeTo) {
  1078. Type[] paramTypes;
  1079. Type returnType;
  1080. InstructionList body;
  1081. InstructionFactory fact;
  1082. int pos;
  1083. ResolvedMember bridgerMethod = AjcMemberMaker.bridgerToInterMethod(unMangledInterMethod, classGen.getType());
  1084. ResolvedMember bridgingSetter = AjcMemberMaker.interMethodBridger(toBridgeTo, aspectType, false); // pr250493
  1085. LazyMethodGen bridgeMethod = makeMethodGen(classGen, bridgingSetter);
  1086. paramTypes = BcelWorld.makeBcelTypes(bridgingSetter.getParameterTypes());
  1087. Type[] bridgingToParms = BcelWorld.makeBcelTypes(unMangledInterMethod.getParameterTypes());
  1088. returnType = BcelWorld.makeBcelType(bridgingSetter.getReturnType());
  1089. body = bridgeMethod.getBody();
  1090. fact = classGen.getFactory();
  1091. pos = 0;
  1092. if (!Modifier.isStatic(bridgingSetter.getModifiers())) {
  1093. body.append(InstructionFactory.createThis());
  1094. pos++;
  1095. }
  1096. for (int i = 0, len = paramTypes.length; i < len; i++) {
  1097. Type paramType = paramTypes[i];
  1098. body.append(InstructionFactory.createLoad(paramType, pos));
  1099. if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(
  1100. unMangledInterMethod.getParameterTypes()[i].getErasureSignature())) {
  1101. // System.err.println("Putting in cast from "+
  1102. // paramType+" to "+bridgingToParms[i]);
  1103. body.append(fact.createCast(paramType, bridgingToParms[i]));
  1104. }
  1105. pos += paramType.getSize();
  1106. }
  1107. body.append(Utility.createInvoke(fact, weaver.getWorld(), bridgerMethod));
  1108. body.append(InstructionFactory.createReturn(returnType));
  1109. classGen.addMethodGen(bridgeMethod);
  1110. // mg.definingType = onType;
  1111. }
  1112. /**
  1113. * Helper method to create a signature attribute based on a string signature: e.g. "Ljava/lang/Object;LI<Ljava/lang/Double;>;"
  1114. */
  1115. private Signature createSignatureAttribute(ConstantPool cp, String signature) {
  1116. int nameIndex = cp.addUtf8("Signature");
  1117. int sigIndex = cp.addUtf8(signature);
  1118. return new Signature(nameIndex, 2, sigIndex, cp);
  1119. }
  1120. /**
  1121. * Create any bridge method required because of covariant returns being used. This method is used in the case where an ITD is
  1122. * applied to some type and it may be in an override relationship with a method from the supertype - but due to covariance there
  1123. * is a mismatch in return values. Example of when required: Super defines: Object m(String s) Sub defines: String m(String s)
  1124. * then we need a bridge method in Sub called 'Object m(String s)' that forwards to 'String m(String s)'
  1125. */
  1126. private void createAnyBridgeMethodsForCovariance(BcelClassWeaver weaver, NewMethodTypeMunger munger,
  1127. ResolvedMember unMangledInterMethod, ResolvedType onType, LazyClassGen gen, Type[] paramTypes) {
  1128. // PERFORMANCE BOTTLENECK? Might need investigating, method analysis
  1129. // between types in a hierarchy just seems expensive...
  1130. // COVARIANCE BRIDGING
  1131. // Algorithm: Step1. Check in this type - has someone already created
  1132. // the bridge method?
  1133. // Step2. Look above us - do we 'override' a method and yet differ in
  1134. // return type (i.e. covariance)
  1135. // Step3. Create a forwarding bridge method
  1136. // ResolvedType superclass = onType.getSuperclass();
  1137. boolean quitRightNow = false;
  1138. String localMethodName = unMangledInterMethod.getName();
  1139. String erasedSig = unMangledInterMethod.getSignatureErased(); // will be something like (LSuperB;)LFoo;
  1140. String localParameterSig = erasedSig.substring(0,erasedSig.lastIndexOf(')')+1);//unMangledInterMethod.getParameterSignature();
  1141. // getParameterSignatureErased() does not include parens, which we do need.
  1142. String localReturnTypeESig = unMangledInterMethod.getReturnType().getErasureSignature();
  1143. // Step1
  1144. boolean alreadyDone = false; // Compiler might have done it
  1145. ResolvedMember[] localMethods = onType.getDeclaredMethods();
  1146. for (ResolvedMember member : localMethods) {
  1147. if (member.getName().equals(localMethodName)) {
  1148. // Check the params
  1149. if (member.getParameterSignature().equals(localParameterSig)) {
  1150. alreadyDone = true;
  1151. }
  1152. }
  1153. }
  1154. // Step2
  1155. if (!alreadyDone) {
  1156. // Use the iterator form of 'getMethods()' so we do as little work as necessary
  1157. ResolvedType supertype = onType.getSuperclass();
  1158. if (supertype != null) {
  1159. for (Iterator<ResolvedMember> iter = supertype.getMethods(true, true); iter.hasNext() && !quitRightNow;) {
  1160. ResolvedMember aMethod = iter.next();
  1161. if (aMethod.getName().equals(localMethodName) && aMethod.getParameterSignature().equals(localParameterSig)) {
  1162. // check the return types, if they are different we need a
  1163. // bridging method.
  1164. if (!aMethod.getReturnType().getErasureSignature().equals(localReturnTypeESig)
  1165. && !Modifier.isPrivate(aMethod.getModifiers())) {
  1166. // Step3
  1167. createBridgeMethod(weaver.getWorld(), munger, unMangledInterMethod, gen, paramTypes, aMethod);
  1168. quitRightNow = true;
  1169. }
  1170. }
  1171. }
  1172. }
  1173. }
  1174. }
  1175. /**
  1176. * Create a bridge method for a particular munger.
  1177. *
  1178. * @param world
  1179. * @param munger
  1180. * @param unMangledInterMethod the method to bridge 'to' that we have already created in the 'subtype'
  1181. * @param clazz the class in which to put the bridge method
  1182. * @param paramTypes Parameter types for the bridge method, passed in as an optimization since the caller is likely to have
  1183. * already created them.
  1184. * @param theBridgeMethod
  1185. */
  1186. private void createBridgeMethod(BcelWorld world, NewMethodTypeMunger munger, ResolvedMember unMangledInterMethod,
  1187. LazyClassGen clazz, Type[] paramTypes, ResolvedMember theBridgeMethod) {
  1188. InstructionList body;
  1189. InstructionFactory fact;
  1190. int pos = 0;
  1191. // The bridge method in this type will have the same signature as the one in the supertype
  1192. LazyMethodGen bridgeMethod = makeMethodGen(clazz, theBridgeMethod);
  1193. bridgeMethod.setAccessFlags(bridgeMethod.getAccessFlags() | 0x00000040 /* BRIDGE = 0x00000040 */);
  1194. // UnresolvedType[] newParams = munger.getSignature().getParameterTypes();
  1195. Type returnType = BcelWorld.makeBcelType(theBridgeMethod.getReturnType());
  1196. body = bridgeMethod.getBody();
  1197. fact = clazz.getFactory();
  1198. if (!Modifier.isStatic(unMangledInterMethod.getModifiers())) {
  1199. body.append(InstructionFactory.createThis());
  1200. pos++;
  1201. }
  1202. for (Type paramType : paramTypes) {
  1203. body.append(InstructionFactory.createLoad(paramType, pos));
  1204. // if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().
  1205. // equals
  1206. // (unMangledInterMethod.getParameterTypes()[i].getErasureSignature
  1207. // ())) {
  1208. // System.err.println("Putting in cast from "+paramType+" to "+
  1209. // bridgingToParms[i]);
  1210. // body.append(fact.createCast(paramType,bridgingToParms[i]));
  1211. // }
  1212. pos += paramType.getSize();
  1213. }
  1214. body.append(Utility.createInvoke(fact, world, unMangledInterMethod));
  1215. body.append(InstructionFactory.createReturn(returnType));
  1216. clazz.addMethodGen(bridgeMethod);
  1217. }
  1218. // Unlike toString() on a member, this does not include the declaring type
  1219. private String stringifyMember(ResolvedMember member) {
  1220. StringBuffer buf = new StringBuffer();
  1221. buf.append(member.getReturnType().getName());
  1222. buf.append(' ');
  1223. buf.append(member.getName());
  1224. if (member.getKind() != Member.FIELD) {
  1225. buf.append("(");
  1226. UnresolvedType[] params = member.getParameterTypes();
  1227. if (params.length != 0) {
  1228. buf.append(params[0]);
  1229. for (int i = 1, len = params.length; i < len; i++) {
  1230. buf.append(", ");
  1231. buf.append(params[i].getName());
  1232. }
  1233. }
  1234. buf.append(")");
  1235. }
  1236. return buf.toString();
  1237. }
  1238. private boolean mungeMethodDelegate(BcelClassWeaver weaver, MethodDelegateTypeMunger munger) {
  1239. World world = weaver.getWorld();
  1240. LazyClassGen gen = weaver.getLazyClassGen();
  1241. if (gen.getType().isAnnotation() || gen.getType().isEnum()) {
  1242. // don't signal error as it could be a consequence of a wild type pattern
  1243. return false;
  1244. }
  1245. ResolvedMember introduced = munger.getSignature();
  1246. ResolvedType fromType = world.resolve(introduced.getDeclaringType(), munger.getSourceLocation());
  1247. if (fromType.isRawType()) {
  1248. fromType = fromType.getGenericType();
  1249. }
  1250. boolean shouldApply = munger.matches(weaver.getLazyClassGen().getType(), aspectType);
  1251. if (shouldApply) {
  1252. Type bcelReturnType = BcelWorld.makeBcelType(introduced.getReturnType());
  1253. // If no implementation class was specified, the intention was that
  1254. // the types matching the pattern
  1255. // already implemented the interface, let's check that now!
  1256. if (munger.getImplClassName() == null && !munger.specifiesDelegateFactoryMethod()) {
  1257. boolean isOK = false;
  1258. List<LazyMethodGen> existingMethods = gen.getMethodGens();
  1259. for (LazyMethodGen m : existingMethods) {
  1260. if (m.getName().equals(introduced.getName())
  1261. && m.getParameterSignature().equals(introduced.getParameterSignature())
  1262. && m.getReturnType().equals(bcelReturnType)) {
  1263. isOK = true;
  1264. }
  1265. }
  1266. if (!isOK) {
  1267. // the class does not implement this method, they needed to
  1268. // supply a default impl class
  1269. IMessage msg = new Message("@DeclareParents: No defaultImpl was specified but the type '" + gen.getName()
  1270. + "' does not implement the method '" + stringifyMember(introduced) + "' defined on the interface '"
  1271. + introduced.getDeclaringType() + "'", weaver.getLazyClassGen().getType().getSourceLocation(), true,
  1272. new ISourceLocation[] { munger.getSourceLocation() });
  1273. weaver.getWorld().getMessageHandler().handleMessage(msg);
  1274. return false;
  1275. }
  1276. return true;
  1277. }
  1278. LazyMethodGen mg = new LazyMethodGen(introduced.getModifiers() - Modifier.ABSTRACT, bcelReturnType,
  1279. introduced.getName(), BcelWorld.makeBcelTypes(introduced.getParameterTypes()),
  1280. BcelWorld.makeBcelTypesAsClassNames(introduced.getExceptions()), gen);
  1281. // annotation copy from annotation on ITD interface
  1282. if (weaver.getWorld().isInJava5Mode()) {
  1283. AnnotationAJ annotationsOnRealMember[] = null;
  1284. ResolvedType toLookOn = weaver.getWorld().lookupOrCreateName(introduced.getDeclaringType());
  1285. if (fromType.isRawType()) {
  1286. toLookOn = fromType.getGenericType();
  1287. }
  1288. // lookup the method
  1289. ResolvedMember[] ms = toLookOn.getDeclaredJavaMethods();
  1290. for (ResolvedMember m : ms) {
  1291. if (introduced.getName().equals(m.getName()) && introduced.getSignature().equals(m.getSignature())) {
  1292. annotationsOnRealMember = m.getAnnotations();
  1293. break;
  1294. }
  1295. }
  1296. if (annotationsOnRealMember != null) {
  1297. for (AnnotationAJ anno : annotationsOnRealMember) {
  1298. AnnotationGen a = ((BcelAnnotation) anno).getBcelAnnotation();
  1299. AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true);
  1300. mg.addAnnotation(new BcelAnnotation(ag, weaver.getWorld()));
  1301. }
  1302. }
  1303. }
  1304. InstructionList body = new InstructionList();
  1305. InstructionFactory fact = gen.getFactory();
  1306. // getfield
  1307. body.append(InstructionConstants.ALOAD_0);
  1308. body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
  1309. InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
  1310. body.append(ifNonNull);
  1311. // Create and store a new instance
  1312. body.append(InstructionConstants.ALOAD_0); // 'this' is where we'll store the field value
  1313. // TODO for non-static case, call aspectOf() then call the factory method on the retval
  1314. // TODO decide whether the value can really be cached
  1315. // locate the aspect and call the static method in it
  1316. if (munger.specifiesDelegateFactoryMethod()) {
  1317. ResolvedMember rm = munger.getDelegateFactoryMethod(weaver.getWorld());
  1318. // Check the method parameter is compatible with the type of the instance to be passed
  1319. if (rm.getArity() != 0) {
  1320. ResolvedType parameterType = rm.getParameterTypes()[0].resolve(weaver.getWorld());
  1321. if (!parameterType.isAssignableFrom(weaver.getLazyClassGen().getType())) {
  1322. signalError("For mixin factory method '" + rm + "': Instance type '" + weaver.getLazyClassGen().getType()
  1323. + "' is not compatible with factory parameter type '" + parameterType + "'", weaver);
  1324. return false;
  1325. }
  1326. }
  1327. if (Modifier.isStatic(rm.getModifiers())) {
  1328. if (rm.getArity() != 0) {
  1329. body.append(InstructionConstants.ALOAD_0);
  1330. }
  1331. body.append(fact.createInvoke(rm.getDeclaringType().getName(), rm.getName(), rm.getSignature(),
  1332. Constants.INVOKESTATIC));
  1333. body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
  1334. } else {
  1335. // Need to call aspectOf() to obtain the aspect instance then call the factory method upon that
  1336. UnresolvedType theAspect = munger.getAspect();
  1337. body.append(fact.createInvoke(theAspect.getName(), "aspectOf", "()" + theAspect.getSignature(),
  1338. Constants.INVOKESTATIC));
  1339. if (rm.getArity() != 0) {
  1340. body.append(InstructionConstants.ALOAD_0);
  1341. }
  1342. body.append(fact.createInvoke(rm.getDeclaringType().getName(), rm.getName(), rm.getSignature(),
  1343. Constants.INVOKEVIRTUAL));
  1344. body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
  1345. }
  1346. } else {
  1347. body.append(fact.createNew(munger.getImplClassName()));
  1348. body.append(InstructionConstants.DUP);
  1349. body.append(fact.createInvoke(munger.getImplClassName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
  1350. body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
  1351. }
  1352. // if not null use the instance we've got
  1353. InstructionHandle ifNonNullElse = body.append(InstructionConstants.ALOAD_0);
  1354. ifNonNull.setTarget(ifNonNullElse);
  1355. body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
  1356. // args
  1357. int pos = 0;
  1358. if (!Modifier.isStatic(introduced.getModifiers())) { // skip 'this' (?? can this really
  1359. // happen)
  1360. // body.append(InstructionFactory.createThis());
  1361. pos++;
  1362. }
  1363. Type[] paramTypes = BcelWorld.makeBcelTypes(introduced.getParameterTypes());
  1364. for (Type paramType : paramTypes) {
  1365. body.append(InstructionFactory.createLoad(paramType, pos));
  1366. pos += paramType.getSize();
  1367. }
  1368. body.append(Utility.createInvoke(fact, Constants.INVOKEINTERFACE, introduced));
  1369. body.append(InstructionFactory.createReturn(bcelReturnType));
  1370. mg.getBody().append(body);
  1371. weaver.addLazyMethodGen(mg);
  1372. weaver.getLazyClassGen().warnOnAddedMethod(mg.getMethod(), getSignature().getSourceLocation());
  1373. return true;
  1374. }
  1375. return false;
  1376. }
  1377. private boolean mungeFieldHost(BcelClassWeaver weaver, MethodDelegateTypeMunger.FieldHostTypeMunger munger) {
  1378. LazyClassGen gen = weaver.getLazyClassGen();
  1379. if (gen.getType().isAnnotation() || gen.getType().isEnum()) {
  1380. // don't signal error as it could be a consequence of a wild type
  1381. // pattern
  1382. return false;
  1383. }
  1384. // boolean shouldApply =
  1385. munger.matches(weaver.getLazyClassGen().getType(), aspectType); // why
  1386. // do
  1387. // this?
  1388. ResolvedMember host = AjcMemberMaker.itdAtDeclareParentsField(weaver.getLazyClassGen().getType(), munger.getSignature()
  1389. .getType(), aspectType);
  1390. FieldGen field = makeFieldGen(weaver.getLazyClassGen(), host);
  1391. field.setModifiers(field.getModifiers() | BcelField.AccSynthetic);
  1392. weaver.getLazyClassGen().addField(field, null);
  1393. return true;
  1394. }
  1395. private ResolvedMember getRealMemberForITDFromAspect(ResolvedType aspectType, ResolvedMember lookingFor, boolean isCtorRelated) {
  1396. World world = aspectType.getWorld();
  1397. boolean debug = false;
  1398. if (debug) {
  1399. System.err.println("Searching for a member on type: " + aspectType);
  1400. System.err.println("Member we are looking for: " + lookingFor);
  1401. }
  1402. ResolvedMember aspectMethods[] = aspectType.getDeclaredMethods();
  1403. UnresolvedType[] lookingForParams = lookingFor.getParameterTypes();
  1404. ResolvedMember realMember = null;
  1405. for (int i = 0; realMember == null && i < aspectMethods.length; i++) {
  1406. ResolvedMember member = aspectMethods[i];
  1407. if (member.getName().equals(lookingFor.getName())) {
  1408. UnresolvedType[] memberParams = member.getGenericParameterTypes();
  1409. if (memberParams.length == lookingForParams.length) {
  1410. if (debug) {
  1411. System.err.println("Reviewing potential candidates: " + member);
  1412. }
  1413. boolean matchOK = true;
  1414. // If not related to a ctor ITD then the name is enough to
  1415. // confirm we have the
  1416. // right one. If it is ctor related we need to check the
  1417. // params all match, although
  1418. // only the erasure.
  1419. if (isCtorRelated) {
  1420. for (int j = 0; j < memberParams.length && matchOK; j++) {
  1421. ResolvedType pMember = memberParams[j].resolve(world);
  1422. ResolvedType pLookingFor = lookingForParams[j].resolve(world);
  1423. if (pMember.isTypeVariableReference()) {
  1424. pMember = ((TypeVariableReference) pMember).getTypeVariable().getFirstBound().resolve(world);
  1425. }
  1426. if (pMember.isParameterizedType() || pMember.isGenericType()) {
  1427. pMember = pMember.getRawType().resolve(aspectType.getWorld());
  1428. }
  1429. if (pLookingFor.isTypeVariableReference()) {
  1430. pLookingFor = ((TypeVariableReference) pLookingFor).getTypeVariable().getFirstBound()
  1431. .resolve(world);
  1432. }
  1433. if (pLookingFor.isParameterizedType() || pLookingFor.isGenericType()) {
  1434. pLookingFor = pLookingFor.getRawType().resolve(world);
  1435. }
  1436. if (debug) {
  1437. System.err.println("Comparing parameter " + j + " member=" + pMember + " lookingFor="
  1438. + pLookingFor);
  1439. }
  1440. if (!pMember.equals(pLookingFor)) {
  1441. matchOK = false;
  1442. }
  1443. }
  1444. }
  1445. if (matchOK) {
  1446. realMember = member;
  1447. }
  1448. }
  1449. }
  1450. }
  1451. if (debug && realMember == null) {
  1452. System.err.println("Didn't find a match");
  1453. }
  1454. return realMember;
  1455. }
  1456. private void addNeededSuperCallMethods(BcelClassWeaver weaver, ResolvedType onType, Set<ResolvedMember> neededSuperCalls) {
  1457. LazyClassGen gen = weaver.getLazyClassGen();
  1458. for (ResolvedMember superMethod: neededSuperCalls) {
  1459. if (weaver.addDispatchTarget(superMethod)) {
  1460. // System.err.println("super type: " + superMethod.getDeclaringType() + ", " + gen.getType());
  1461. boolean isSuper = !superMethod.getDeclaringType().equals(gen.getType());
  1462. String dispatchName;
  1463. if (isSuper) {
  1464. dispatchName = NameMangler.superDispatchMethod(onType, superMethod.getName());
  1465. } else {
  1466. dispatchName = NameMangler.protectedDispatchMethod(onType, superMethod.getName());
  1467. }
  1468. superMethod = superMethod.resolve(weaver.getWorld());
  1469. LazyMethodGen dispatcher = makeDispatcher(gen, dispatchName, superMethod, weaver.getWorld(), isSuper);
  1470. weaver.addLazyMethodGen(dispatcher);
  1471. }
  1472. }
  1473. }
  1474. private void signalError(String msgid, BcelClassWeaver weaver, UnresolvedType onType) {
  1475. IMessage msg = MessageUtil.error(WeaverMessages.format(msgid, onType.getName()), getSourceLocation());
  1476. weaver.getWorld().getMessageHandler().handleMessage(msg);
  1477. }
  1478. // private void signalWarning(String msgString, BcelClassWeaver weaver) {
  1479. // IMessage msg = MessageUtil.warn(msgString, getSourceLocation());
  1480. // weaver.getWorld().getMessageHandler().handleMessage(msg);
  1481. // }
  1482. private void signalError(String msgString, BcelClassWeaver weaver) {
  1483. IMessage msg = MessageUtil.error(msgString, getSourceLocation());
  1484. weaver.getWorld().getMessageHandler().handleMessage(msg);
  1485. }
  1486. private boolean mungeNewConstructor(BcelClassWeaver weaver, NewConstructorTypeMunger newConstructorTypeMunger) {
  1487. final LazyClassGen currentClass = weaver.getLazyClassGen();
  1488. final InstructionFactory fact = currentClass.getFactory();
  1489. ResolvedMember newConstructorMember = newConstructorTypeMunger.getSyntheticConstructor();
  1490. ResolvedType onType = newConstructorMember.getDeclaringType().resolve(weaver.getWorld());
  1491. if (onType.isRawType()) {
  1492. onType = onType.getGenericType();
  1493. }
  1494. if (onType.isAnnotation()) {
  1495. signalError(WeaverMessages.ITDC_ON_ANNOTATION_NOT_ALLOWED, weaver, onType);
  1496. return false;
  1497. }
  1498. if (onType.isEnum()) {
  1499. signalError(WeaverMessages.ITDC_ON_ENUM_NOT_ALLOWED, weaver, onType);
  1500. return false;
  1501. }
  1502. if (!onType.equals(currentClass.getType())) {
  1503. return false;
  1504. }
  1505. ResolvedMember explicitConstructor = newConstructorTypeMunger.getExplicitConstructor();
  1506. // int declaredParameterCount =
  1507. // newConstructorTypeMunger.getDeclaredParameterCount();
  1508. LazyMethodGen mg = makeMethodGen(currentClass, newConstructorMember);
  1509. mg.setEffectiveSignature(newConstructorTypeMunger.getSignature(), Shadow.ConstructorExecution, true);
  1510. // pr98901
  1511. // For copying the annotations across, we have to discover the real
  1512. // member in the aspect
  1513. // which is holding them.
  1514. if (weaver.getWorld().isInJava5Mode()) {
  1515. ResolvedMember interMethodDispatcher = AjcMemberMaker.postIntroducedConstructor(aspectType, onType,
  1516. newConstructorTypeMunger.getSignature().getParameterTypes());
  1517. AnnotationAJ annotationsOnRealMember[] = null;
  1518. ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType, interMethodDispatcher, true);
  1519. // 266602 - consider it missing to mean that the corresponding aspect had errors
  1520. if (realMember == null) {
  1521. // signalWarning("Unable to apply any annotations attached to " + munger.getSignature(), weaver);
  1522. // throw new BCException("Couldn't find ITD init member '" + interMethodBody + "' on aspect " + aspectType);
  1523. } else {
  1524. annotationsOnRealMember = realMember.getAnnotations();
  1525. }
  1526. if (annotationsOnRealMember != null) {
  1527. for (AnnotationAJ annotationX : annotationsOnRealMember) {
  1528. AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
  1529. AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true);
  1530. mg.addAnnotation(new BcelAnnotation(ag, weaver.getWorld()));
  1531. }
  1532. }
  1533. // the below loop fixes the very special (and very stupid)
  1534. // case where an aspect declares an annotation
  1535. // on an ITD it declared on itself.
  1536. List<DeclareAnnotation> allDecams = weaver.getWorld().getDeclareAnnotationOnMethods();
  1537. for (DeclareAnnotation decaMC : allDecams) {
  1538. if (decaMC.matches(explicitConstructor, weaver.getWorld()) && mg.getEnclosingClass().getType() == aspectType) {
  1539. mg.addAnnotation(decaMC.getAnnotation());
  1540. }
  1541. }
  1542. }
  1543. // Might have to remove the default constructor - b275032
  1544. // TODO could have tagged the type munger when the fact we needed to do this was detected earlier
  1545. if (mg.getArgumentTypes().length == 0) {
  1546. LazyMethodGen toRemove = null;
  1547. for (LazyMethodGen object : currentClass.getMethodGens()) {
  1548. if (object.getName().equals("<init>") && object.getArgumentTypes().length == 0) {
  1549. toRemove = object;
  1550. }
  1551. }
  1552. if (toRemove != null) {
  1553. currentClass.removeMethodGen(toRemove);
  1554. }
  1555. }
  1556. currentClass.addMethodGen(mg);
  1557. // weaver.addLazyMethodGen(freshConstructor);
  1558. InstructionList body = mg.getBody();
  1559. // add to body: push arts for call to pre, from actual args starting at
  1560. // 1 (skipping this), going to
  1561. // declared argcount + 1
  1562. UnresolvedType[] declaredParams = newConstructorTypeMunger.getSignature().getParameterTypes();
  1563. Type[] paramTypes = mg.getArgumentTypes();
  1564. int frameIndex = 1;
  1565. for (int i = 0, len = declaredParams.length; i < len; i++) {
  1566. body.append(InstructionFactory.createLoad(paramTypes[i], frameIndex));
  1567. frameIndex += paramTypes[i].getSize();
  1568. }
  1569. // do call to pre
  1570. Member preMethod = AjcMemberMaker.preIntroducedConstructor(aspectType, onType, declaredParams);
  1571. body.append(Utility.createInvoke(fact, null, preMethod));
  1572. // create a local, and store return pre stuff into it.
  1573. int arraySlot = mg.allocateLocal(1);
  1574. body.append(InstructionFactory.createStore(Type.OBJECT, arraySlot));
  1575. // put this on the stack
  1576. body.append(InstructionConstants.ALOAD_0);
  1577. // unpack pre args onto stack
  1578. UnresolvedType[] superParamTypes = explicitConstructor.getParameterTypes();
  1579. for (int i = 0, len = superParamTypes.length; i < len; i++) {
  1580. body.append(InstructionFactory.createLoad(Type.OBJECT, arraySlot));
  1581. body.append(Utility.createConstant(fact, i));
  1582. body.append(InstructionFactory.createArrayLoad(Type.OBJECT));
  1583. body.append(Utility.createConversion(fact, Type.OBJECT, BcelWorld.makeBcelType(superParamTypes[i])));
  1584. }
  1585. // call super/this
  1586. body.append(Utility.createInvoke(fact, null, explicitConstructor));
  1587. // put this back on the stack
  1588. body.append(InstructionConstants.ALOAD_0);
  1589. // unpack params onto stack
  1590. Member postMethod = AjcMemberMaker.postIntroducedConstructor(aspectType, onType, declaredParams);
  1591. UnresolvedType[] postParamTypes = postMethod.getParameterTypes();
  1592. for (int i = 1, len = postParamTypes.length; i < len; i++) {
  1593. body.append(InstructionFactory.createLoad(Type.OBJECT, arraySlot));
  1594. body.append(Utility.createConstant(fact, superParamTypes.length + i - 1));
  1595. body.append(InstructionFactory.createArrayLoad(Type.OBJECT));
  1596. body.append(Utility.createConversion(fact, Type.OBJECT, BcelWorld.makeBcelType(postParamTypes[i])));
  1597. }
  1598. // call post
  1599. body.append(Utility.createInvoke(fact, null, postMethod));
  1600. // don't forget to return!!
  1601. body.append(InstructionConstants.RETURN);
  1602. addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
  1603. return true;
  1604. }
  1605. private static LazyMethodGen makeDispatcher(LazyClassGen onGen, String dispatchName, ResolvedMember superMethod,
  1606. BcelWorld world, boolean isSuper) {
  1607. Type[] paramTypes = BcelWorld.makeBcelTypes(superMethod.getParameterTypes());
  1608. Type returnType = BcelWorld.makeBcelType(superMethod.getReturnType());
  1609. int modifiers = Modifier.PUBLIC;
  1610. if (onGen.isInterface()) {
  1611. modifiers |= Modifier.ABSTRACT;
  1612. }
  1613. LazyMethodGen mg = new LazyMethodGen(modifiers, returnType, dispatchName, paramTypes, UnresolvedType.getNames(superMethod
  1614. .getExceptions()), onGen);
  1615. InstructionList body = mg.getBody();
  1616. if (onGen.isInterface()) {
  1617. return mg;
  1618. }
  1619. // assert (!superMethod.isStatic())
  1620. InstructionFactory fact = onGen.getFactory();
  1621. int pos = 0;
  1622. body.append(InstructionFactory.createThis());
  1623. pos++;
  1624. for (Type paramType : paramTypes) {
  1625. body.append(InstructionFactory.createLoad(paramType, pos));
  1626. pos += paramType.getSize();
  1627. }
  1628. if (isSuper) {
  1629. body.append(Utility.createSuperInvoke(fact, world, superMethod));
  1630. } else {
  1631. body.append(Utility.createInvoke(fact, world, superMethod));
  1632. }
  1633. body.append(InstructionFactory.createReturn(returnType));
  1634. return mg;
  1635. }
  1636. private boolean mungeNewField(BcelClassWeaver weaver, NewFieldTypeMunger munger) {
  1637. /* ResolvedMember initMethod = */munger.getInitMethod(aspectType);
  1638. LazyClassGen gen = weaver.getLazyClassGen();
  1639. ResolvedMember field = munger.getSignature();
  1640. ResolvedType onType = weaver.getWorld().resolve(field.getDeclaringType(), munger.getSourceLocation());
  1641. if (onType.isRawType()) {
  1642. onType = onType.getGenericType();
  1643. }
  1644. boolean onInterface = onType.isInterface();
  1645. if (onType.isAnnotation()) {
  1646. signalError(WeaverMessages.ITDF_ON_ANNOTATION_NOT_ALLOWED, weaver, onType);
  1647. return false;
  1648. }
  1649. if (onType.isEnum()) {
  1650. signalError(WeaverMessages.ITDF_ON_ENUM_NOT_ALLOWED, weaver, onType);
  1651. return false;
  1652. }
  1653. ResolvedMember interMethodBody = munger.getInitMethod(aspectType);
  1654. AnnotationAJ annotationsOnRealMember[] = null;
  1655. // pr98901
  1656. // For copying the annotations across, we have to discover the real
  1657. // member in the aspect
  1658. // which is holding them.
  1659. if (weaver.getWorld().isInJava5Mode()) {
  1660. // the below line just gets the method with the same name in
  1661. // aspectType.getDeclaredMethods();
  1662. ResolvedType toLookOn = aspectType;
  1663. if (aspectType.isRawType()) {
  1664. toLookOn = aspectType.getGenericType();
  1665. }
  1666. ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn, interMethodBody, false);
  1667. if (realMember == null) {
  1668. // signalWarning("Unable to apply any annotations attached to " + munger.getSignature(), weaver);
  1669. // throw new BCException("Couldn't find ITD init member '" + interMethodBody + "' on aspect " + aspectType);
  1670. } else {
  1671. annotationsOnRealMember = realMember.getAnnotations();
  1672. }
  1673. }
  1674. if (onType.equals(gen.getType())) {
  1675. if (onInterface) {
  1676. ResolvedMember itdfieldGetter = AjcMemberMaker.interFieldInterfaceGetter(field, onType, aspectType);
  1677. LazyMethodGen mg = makeMethodGen(gen, itdfieldGetter);
  1678. gen.addMethodGen(mg);
  1679. LazyMethodGen mg1 = makeMethodGen(gen, AjcMemberMaker.interFieldInterfaceSetter(field, onType, aspectType));
  1680. gen.addMethodGen(mg1);
  1681. } else {
  1682. weaver.addInitializer(this);
  1683. ResolvedMember newField = AjcMemberMaker.interFieldClassField(field, aspectType,
  1684. munger.version == NewFieldTypeMunger.VersionTwo);
  1685. FieldGen fg = makeFieldGen(gen, newField);
  1686. if (annotationsOnRealMember != null) {
  1687. for (AnnotationAJ annotationX : annotationsOnRealMember) {
  1688. AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
  1689. AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true);
  1690. fg.addAnnotation(ag);
  1691. }
  1692. }
  1693. if (weaver.getWorld().isInJava5Mode()) {
  1694. String basicSignature = field.getSignature();
  1695. String genericSignature = field.getReturnType().resolve(weaver.getWorld()).getSignatureForAttribute();
  1696. // String genericSignature =
  1697. // ((ResolvedMemberImpl)field).getSignatureForAttribute();
  1698. if (!basicSignature.equals(genericSignature)) {
  1699. // Add a signature attribute to it
  1700. fg.addAttribute(createSignatureAttribute(gen.getConstantPool(), genericSignature));
  1701. }
  1702. }
  1703. gen.addField(fg, getSourceLocation());
  1704. }
  1705. return true;
  1706. } else if (onInterface && gen.getType().isTopmostImplementor(onType)) {
  1707. // we know that we can't be static since we don't allow statics on interfaces
  1708. if (Modifier.isStatic(field.getModifiers())) {
  1709. throw new RuntimeException("unimplemented");
  1710. }
  1711. boolean alreadyExists = false;
  1712. // only need to check for version 2 style mungers
  1713. if (munger.version==NewFieldTypeMunger.VersionTwo) {
  1714. for (BcelField fieldgen: gen.getFieldGens()) {
  1715. if (fieldgen.getName().equals(field.getName())) {
  1716. alreadyExists=true;
  1717. break;
  1718. }
  1719. }
  1720. }
  1721. // FieldGen fg = makeFieldGen(gen, AjcMemberMaker.interFieldInterfaceField(field, onType, aspectType));
  1722. ResolvedMember newField = AjcMemberMaker.interFieldInterfaceField(field, onType, aspectType, munger.version == NewFieldTypeMunger.VersionTwo);
  1723. String fieldName = newField.getName();
  1724. Type fieldType = BcelWorld.makeBcelType(field.getType());
  1725. if (!alreadyExists) {
  1726. weaver.addInitializer(this);
  1727. FieldGen fg = makeFieldGen(gen,newField);
  1728. if (annotationsOnRealMember != null) {
  1729. for (AnnotationAJ annotationX : annotationsOnRealMember) {
  1730. AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
  1731. AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true);
  1732. fg.addAnnotation(ag);
  1733. }
  1734. }
  1735. if (weaver.getWorld().isInJava5Mode()) {
  1736. String basicSignature = field.getSignature();
  1737. String genericSignature = field.getReturnType().resolve(weaver.getWorld()).getSignatureForAttribute();
  1738. // String genericSignature =
  1739. // ((ResolvedMemberImpl)field).getSignatureForAttribute();
  1740. if (!basicSignature.equals(genericSignature)) {
  1741. // Add a signature attribute to it
  1742. fg.addAttribute(createSignatureAttribute(gen.getConstantPool(), genericSignature));
  1743. }
  1744. }
  1745. gen.addField(fg, getSourceLocation());
  1746. }
  1747. // this uses a shadow munger to add init method to constructors
  1748. // weaver.getShadowMungers().add(makeInitCallShadowMunger(initMethod)
  1749. // );
  1750. ResolvedMember itdfieldGetter = AjcMemberMaker.interFieldInterfaceGetter(field, gen.getType()/* onType */, aspectType);
  1751. LazyMethodGen mg = makeMethodGen(gen, itdfieldGetter);
  1752. InstructionList il = new InstructionList();
  1753. InstructionFactory fact = gen.getFactory();
  1754. if (Modifier.isStatic(field.getModifiers())) {
  1755. il.append(fact.createFieldAccess(gen.getClassName(), fieldName, fieldType, Constants.GETSTATIC));
  1756. } else {
  1757. il.append(InstructionConstants.ALOAD_0);
  1758. il.append(fact.createFieldAccess(gen.getClassName(), fieldName, fieldType, Constants.GETFIELD));
  1759. }
  1760. il.append(InstructionFactory.createReturn(fieldType));
  1761. mg.getBody().insert(il);
  1762. gen.addMethodGen(mg);
  1763. // Check if we need bridge methods for the field getter and setter
  1764. if (munger.getDeclaredSignature() != null) { // is this munger a
  1765. // parameterized
  1766. // form of some
  1767. // original munger?
  1768. ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null,
  1769. munger.getSignature().getDeclaringType().resolve(getWorld()), false, munger.getTypeVariableAliases());
  1770. boolean needsbridging = false;
  1771. if (!toBridgeTo.getReturnType().getErasureSignature()
  1772. .equals(munger.getSignature().getReturnType().getErasureSignature())) {
  1773. needsbridging = true;
  1774. }
  1775. if (needsbridging) {
  1776. ResolvedMember bridgingGetter = AjcMemberMaker.interFieldInterfaceGetter(toBridgeTo, gen.getType(), aspectType);
  1777. createBridgeMethodForITDF(weaver, gen, itdfieldGetter, bridgingGetter);
  1778. }
  1779. }
  1780. ResolvedMember itdfieldSetter = AjcMemberMaker.interFieldInterfaceSetter(field, gen.getType(), aspectType);
  1781. LazyMethodGen mg1 = makeMethodGen(gen, itdfieldSetter);
  1782. InstructionList il1 = new InstructionList();
  1783. if (Modifier.isStatic(field.getModifiers())) {
  1784. il1.append(InstructionFactory.createLoad(fieldType, 0));
  1785. il1.append(fact.createFieldAccess(gen.getClassName(), fieldName, fieldType, Constants.PUTSTATIC));
  1786. } else {
  1787. il1.append(InstructionConstants.ALOAD_0);
  1788. il1.append(InstructionFactory.createLoad(fieldType, 1));
  1789. il1.append(fact.createFieldAccess(gen.getClassName(), fieldName, fieldType, Constants.PUTFIELD));
  1790. }
  1791. il1.append(InstructionFactory.createReturn(Type.VOID));
  1792. mg1.getBody().insert(il1);
  1793. gen.addMethodGen(mg1);
  1794. if (munger.getDeclaredSignature() != null) {
  1795. ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null,
  1796. munger.getSignature().getDeclaringType().resolve(getWorld()), false, munger.getTypeVariableAliases());
  1797. boolean needsbridging = false;
  1798. if (!toBridgeTo.getReturnType().getErasureSignature()
  1799. .equals(munger.getSignature().getReturnType().getErasureSignature())) {
  1800. needsbridging = true;
  1801. }
  1802. if (needsbridging) {
  1803. ResolvedMember bridgingSetter = AjcMemberMaker.interFieldInterfaceSetter(toBridgeTo, gen.getType(), aspectType);
  1804. createBridgeMethodForITDF(weaver, gen, itdfieldSetter, bridgingSetter);
  1805. }
  1806. }
  1807. return true;
  1808. } else {
  1809. return false;
  1810. }
  1811. }
  1812. // FIXME asc combine with other createBridge.. method in this class, avoid
  1813. // the duplication...
  1814. private void createBridgeMethodForITDF(BcelClassWeaver weaver, LazyClassGen gen, ResolvedMember itdfieldSetter,
  1815. ResolvedMember bridgingSetter) {
  1816. InstructionFactory fact;
  1817. LazyMethodGen bridgeMethod = makeMethodGen(gen, bridgingSetter);
  1818. bridgeMethod.setAccessFlags(bridgeMethod.getAccessFlags() | 0x00000040); // BRIDGE = 0x00000040
  1819. Type[] paramTypes = BcelWorld.makeBcelTypes(bridgingSetter.getParameterTypes());
  1820. Type[] bridgingToParms = BcelWorld.makeBcelTypes(itdfieldSetter.getParameterTypes());
  1821. Type returnType = BcelWorld.makeBcelType(bridgingSetter.getReturnType());
  1822. InstructionList body = bridgeMethod.getBody();
  1823. fact = gen.getFactory();
  1824. int pos = 0;
  1825. if (!Modifier.isStatic(bridgingSetter.getModifiers())) {
  1826. body.append(InstructionFactory.createThis());
  1827. pos++;
  1828. }
  1829. for (int i = 0, len = paramTypes.length; i < len; i++) {
  1830. Type paramType = paramTypes[i];
  1831. body.append(InstructionFactory.createLoad(paramType, pos));
  1832. if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(
  1833. itdfieldSetter.getParameterTypes()[i].getErasureSignature())) {
  1834. body.append(fact.createCast(paramType, bridgingToParms[i]));
  1835. }
  1836. pos += paramType.getSize();
  1837. }
  1838. body.append(Utility.createInvoke(fact, weaver.getWorld(), itdfieldSetter));
  1839. body.append(InstructionFactory.createReturn(returnType));
  1840. gen.addMethodGen(bridgeMethod);
  1841. }
  1842. @Override
  1843. public ConcreteTypeMunger parameterizedFor(ResolvedType target) {
  1844. return new BcelTypeMunger(munger.parameterizedFor(target), aspectType);
  1845. }
  1846. @Override
  1847. public ConcreteTypeMunger parameterizeWith(Map<String, UnresolvedType> m, World w) {
  1848. return new BcelTypeMunger(munger.parameterizeWith(m, w), aspectType);
  1849. }
  1850. /**
  1851. * Returns a list of type variable aliases used in this munger. For example, if the ITD is 'int I&lt;A,B&gt;.m(List&lt;A&gt; las,List&lt;B&gt;
  1852. * lbs) {}' then this returns a list containing the strings "A" and "B".
  1853. */
  1854. public List<String> getTypeVariableAliases() {
  1855. return munger.getTypeVariableAliases();
  1856. }
  1857. @Override
  1858. public boolean equals(Object other) {
  1859. if (!(other instanceof BcelTypeMunger)) {
  1860. return false;
  1861. }
  1862. BcelTypeMunger o = (BcelTypeMunger) other;
  1863. return ((o.getMunger() == null) ? (getMunger() == null) : o.getMunger().equals(getMunger()))
  1864. && ((o.getAspectType() == null) ? (getAspectType() == null) : o.getAspectType().equals(getAspectType()));
  1865. // && (AsmManager.getDefault().getHandleProvider().dependsOnLocation() ? ((o.getSourceLocation() == null) ?
  1866. // (getSourceLocation() == null)
  1867. // : o.getSourceLocation().equals(getSourceLocation()))
  1868. // : true); // pr134471 - remove when handles are improved
  1869. // to be independent of location
  1870. }
  1871. private volatile int hashCode = 0;
  1872. @Override
  1873. public int hashCode() {
  1874. if (hashCode == 0) {
  1875. int result = 17;
  1876. result = 37 * result + ((getMunger() == null) ? 0 : getMunger().hashCode());
  1877. result = 37 * result + ((getAspectType() == null) ? 0 : getAspectType().hashCode());
  1878. hashCode = result;
  1879. }
  1880. return hashCode;
  1881. }
  1882. }