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.

AjAttribute.java 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  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. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.io.ByteArrayInputStream;
  14. import java.io.ByteArrayOutputStream;
  15. import java.io.DataOutputStream;
  16. import java.io.EOFException;
  17. import java.io.IOException;
  18. import org.aspectj.bridge.MessageUtil;
  19. import org.aspectj.bridge.Version;
  20. import org.aspectj.util.FileUtil;
  21. import org.aspectj.weaver.patterns.Declare;
  22. import org.aspectj.weaver.patterns.IScope;
  23. import org.aspectj.weaver.patterns.PerClause;
  24. import org.aspectj.weaver.patterns.Pointcut;
  25. /**
  26. * These attributes are written to and read from .class files (see the JVM spec).
  27. *
  28. * <p>Each member or type can have a number of AjAttributes. Each
  29. * such attribute is in 1-1 correspondence with an Unknown bcel attribute.
  30. * Creating one of these does NOTHING to the underlying thing, so if you really
  31. * want to add an attribute to a particular thing, well, you'd better actually do that.
  32. *
  33. * @author Erik Hilsdale
  34. * @author Jim Hugunin
  35. */
  36. public abstract class AjAttribute {
  37. public static final String AttributePrefix = "org.aspectj.weaver";
  38. protected abstract void write(DataOutputStream s) throws IOException;
  39. public abstract String getNameString();
  40. public char[] getNameChars() {
  41. return getNameString().toCharArray();
  42. }
  43. /**
  44. * Just writes the contents
  45. */
  46. public byte[] getBytes() {
  47. try {
  48. ByteArrayOutputStream b0 = new ByteArrayOutputStream();
  49. DataOutputStream s0 = new DataOutputStream(b0);
  50. write(s0);
  51. return b0.toByteArray();
  52. } catch (IOException e) {
  53. // shouldn't happen with ByteArrayOutputStreams
  54. throw new RuntimeException("sanity check");
  55. }
  56. }
  57. /**
  58. * Writes the full attribute, i.e. name_index, length, and contents
  59. */
  60. public byte[] getAllBytes(short nameIndex) {
  61. try {
  62. byte[] bytes = getBytes();
  63. ByteArrayOutputStream b0 = new ByteArrayOutputStream();
  64. DataOutputStream s0 = new DataOutputStream(b0);
  65. s0.writeShort(nameIndex);
  66. s0.writeInt(bytes.length);
  67. s0.write(bytes);
  68. return b0.toByteArray();
  69. } catch (IOException e) {
  70. // shouldn't happen with ByteArrayOutputStreams
  71. throw new RuntimeException("sanity check");
  72. }
  73. }
  74. public static AjAttribute read(AjAttribute.WeaverVersionInfo v, String name, byte[] bytes, ISourceContext context,World w) {
  75. try {
  76. if (bytes == null) bytes = new byte[0];
  77. VersionedDataInputStream s = new VersionedDataInputStream(new ByteArrayInputStream(bytes));
  78. s.setVersion(v);
  79. if (name.equals(Aspect.AttributeName)) {
  80. return new Aspect(PerClause.readPerClause(s, context));
  81. } else if (name.equals(MethodDeclarationLineNumberAttribute.AttributeName)) {
  82. return MethodDeclarationLineNumberAttribute.read(s);
  83. } else if (name.equals(WeaverState.AttributeName)) {
  84. return new WeaverState(WeaverStateInfo.read(s, context));
  85. } else if (name.equals(WeaverVersionInfo.AttributeName)) {
  86. return WeaverVersionInfo.read(s);
  87. } else if (name.equals(AdviceAttribute.AttributeName)) {
  88. AdviceAttribute aa = AdviceAttribute.read(s, context);
  89. aa.getPointcut().check(context,w);
  90. return aa;
  91. } else if (name.equals(PointcutDeclarationAttribute.AttributeName)) {
  92. PointcutDeclarationAttribute pda = new PointcutDeclarationAttribute(ResolvedPointcutDefinition.read(s, context));
  93. pda.pointcutDef.getPointcut().check(context,w);
  94. return pda;
  95. } else if (name.equals(TypeMunger.AttributeName)) {
  96. return new TypeMunger(ResolvedTypeMunger.read(s, context));
  97. } else if (name.equals(AjSynthetic.AttributeName)) {
  98. return new AjSynthetic();
  99. } else if (name.equals(DeclareAttribute.AttributeName)) {
  100. return new DeclareAttribute(Declare.read(s, context));
  101. } else if (name.equals(PrivilegedAttribute.AttributeName)) {
  102. return PrivilegedAttribute.read(s, context);
  103. } else if (name.equals(SourceContextAttribute.AttributeName)) {
  104. return SourceContextAttribute.read(s);
  105. } else if (name.equals(EffectiveSignatureAttribute.AttributeName)) {
  106. return EffectiveSignatureAttribute.read(s, context);
  107. } else {
  108. // We have to tell the user about this...
  109. if (w == null || w.getMessageHandler()==null) throw new BCException("unknown attribute" + name);
  110. w.getMessageHandler().handleMessage(MessageUtil.warn("unknown attribute encountered "+name));
  111. return null;
  112. }
  113. } catch (IOException e) {
  114. throw new BCException("malformed " + name + " attribute " + e);
  115. }
  116. }
  117. //----
  118. /** Synthetic members should have NO advice put on them or on their contents.
  119. * This attribute is currently unused as we consider all members starting
  120. * with NameMangler.PREFIX to automatically be synthetic. As we use this we might
  121. * find that we want multiple
  122. * kinds of synthetic. In particular, if we want to treat the call to a synthetic getter
  123. * (say, of an introduced field) as a field reference itself, then a method might want
  124. * a particular kind of AjSynthetic attribute that also includes a signature of what
  125. * it stands for.
  126. */
  127. public static class AjSynthetic extends AjAttribute {
  128. public static final String AttributeName = "org.aspectj.weaver.AjSynthetic";
  129. public String getNameString() {
  130. return AttributeName;
  131. }
  132. // private ResolvedTypeMunger munger;
  133. public AjSynthetic() {}
  134. public void write(DataOutputStream s) throws IOException {}
  135. }
  136. public static class TypeMunger extends AjAttribute {
  137. public static final String AttributeName = "org.aspectj.weaver.TypeMunger";
  138. public String getNameString() {
  139. return AttributeName;
  140. }
  141. private ResolvedTypeMunger munger;
  142. public TypeMunger(ResolvedTypeMunger munger) {
  143. this.munger = munger;
  144. }
  145. public void write(DataOutputStream s) throws IOException {
  146. munger.write(s);
  147. }
  148. public ConcreteTypeMunger reify(World world, ResolvedType aspectType) {
  149. return world.concreteTypeMunger(munger, aspectType);
  150. }
  151. }
  152. public static class WeaverState extends AjAttribute {
  153. public static final String AttributeName = "org.aspectj.weaver.WeaverState";
  154. public String getNameString() {
  155. return AttributeName;
  156. }
  157. private WeaverStateInfo kind;
  158. public WeaverState(WeaverStateInfo kind) {
  159. this.kind = kind;
  160. }
  161. public void write(DataOutputStream s) throws IOException {
  162. kind.write(s);
  163. }
  164. public WeaverStateInfo reify() {
  165. return kind;
  166. }
  167. }
  168. public static class WeaverVersionInfo extends AjAttribute {
  169. public static final String AttributeName = "org.aspectj.weaver.WeaverVersion";
  170. // If you change the format of an AspectJ class file, you have two options:
  171. // - changing the minor version means you have not added anything that prevents
  172. // previous versions of the weaver from operating (e.g. MethodDeclarationLineNumber attribute)
  173. // - changing the major version means you have added something that prevents previous
  174. // versions of the weaver from operating correctly.
  175. //
  176. // The user will get a warning for any org.aspectj.weaver attributes the weaver does
  177. // not recognize.
  178. // When we don't know ... (i.e. pre 1.2.1)
  179. public static short WEAVER_VERSION_MAJOR_UNKNOWN = 0;
  180. public static short WEAVER_VERSION_MINOR_UNKNOWN = 0;
  181. // These are the weaver major/minor numbers for AspectJ 1.2.1
  182. public static short WEAVER_VERSION_MAJOR_AJ121 = 1;
  183. public static short WEAVER_VERSION_MINOR_AJ121 = 0;
  184. // These are the weaver major/minor numbers for AspectJ 1.5.0
  185. public static short WEAVER_VERSION_MAJOR_AJ150M4 = 3;
  186. public static short WEAVER_VERSION_MAJOR_AJ150 = 2;
  187. public static short WEAVER_VERSION_MINOR_AJ150 = 0;
  188. // These are the weaver major/minor numbers for AspectJ 1.6.0
  189. public static short WEAVER_VERSION_MAJOR_AJ160M2 = 5;
  190. public static short WEAVER_VERSION_MAJOR_AJ160 = 4;
  191. public static short WEAVER_VERSION_MINOR_AJ160 = 0;
  192. // These are the weaver major/minor versions for *this* weaver
  193. private static short CURRENT_VERSION_MAJOR = WEAVER_VERSION_MAJOR_AJ160M2;
  194. private static short CURRENT_VERSION_MINOR = WEAVER_VERSION_MINOR_AJ160;
  195. public static final WeaverVersionInfo UNKNOWN =
  196. new WeaverVersionInfo(WEAVER_VERSION_MAJOR_UNKNOWN,WEAVER_VERSION_MINOR_UNKNOWN);
  197. public static final WeaverVersionInfo CURRENT =
  198. new WeaverVersionInfo(CURRENT_VERSION_MAJOR,CURRENT_VERSION_MINOR);
  199. // These are the versions read in from a particular class file.
  200. private short major_version;
  201. private short minor_version;
  202. private long buildstamp = Version.NOTIME;
  203. public String getNameString() {
  204. return AttributeName;
  205. }
  206. // Default ctor uses the current version numbers
  207. public WeaverVersionInfo() {
  208. this.major_version = CURRENT_VERSION_MAJOR;
  209. this.minor_version = CURRENT_VERSION_MINOR;
  210. }
  211. public WeaverVersionInfo(short major,short minor) {
  212. major_version = major;
  213. minor_version = minor;
  214. }
  215. public void write(DataOutputStream s) throws IOException {
  216. s.writeShort(CURRENT_VERSION_MAJOR);
  217. s.writeShort(CURRENT_VERSION_MINOR);
  218. s.writeLong(Version.getTime()); // build used to construct the class...
  219. }
  220. public static WeaverVersionInfo read(VersionedDataInputStream s) throws IOException {
  221. short major = s.readShort();
  222. short minor = s.readShort();
  223. WeaverVersionInfo wvi = new WeaverVersionInfo(major,minor);
  224. if (s.getMajorVersion()>=WEAVER_VERSION_MAJOR_AJ150M4) {
  225. long stamp = 0;
  226. try {
  227. stamp = s.readLong();
  228. wvi.setBuildstamp(stamp);
  229. } catch (EOFException eof) {
  230. // didnt find that build stamp - its not the end of the world
  231. }
  232. }
  233. return wvi;
  234. }
  235. public short getMajorVersion() {
  236. return major_version;
  237. }
  238. public short getMinorVersion() {
  239. return minor_version;
  240. }
  241. public static short getCurrentWeaverMajorVersion() {
  242. return CURRENT_VERSION_MAJOR;
  243. }
  244. public static short getCurrentWeaverMinorVersion() {
  245. return CURRENT_VERSION_MINOR;
  246. }
  247. public void setBuildstamp(long stamp) {
  248. this.buildstamp = stamp;
  249. }
  250. public long getBuildstamp() {
  251. return buildstamp;
  252. }
  253. public String toString() {
  254. return major_version+"."+minor_version;
  255. }
  256. public static String toCurrentVersionString() {
  257. return CURRENT_VERSION_MAJOR+"."+CURRENT_VERSION_MINOR;
  258. }
  259. }
  260. public static class SourceContextAttribute extends AjAttribute {
  261. public static final String AttributeName = "org.aspectj.weaver.SourceContext";
  262. public String getNameString() {
  263. return AttributeName;
  264. }
  265. private String sourceFileName;
  266. private int[] lineBreaks;
  267. public SourceContextAttribute(String sourceFileName, int[] lineBreaks) {
  268. this.sourceFileName = sourceFileName;
  269. this.lineBreaks = lineBreaks;
  270. }
  271. public void write(DataOutputStream s) throws IOException {
  272. s.writeUTF(sourceFileName);
  273. FileUtil.writeIntArray(lineBreaks, s);
  274. }
  275. public static SourceContextAttribute read(VersionedDataInputStream s) throws IOException {
  276. return new SourceContextAttribute(s.readUTF(), FileUtil.readIntArray(s));
  277. }
  278. public int[] getLineBreaks() {
  279. return lineBreaks;
  280. }
  281. public String getSourceFileName() {
  282. return sourceFileName;
  283. }
  284. }
  285. public static class MethodDeclarationLineNumberAttribute extends AjAttribute {
  286. public static final String AttributeName = "org.aspectj.weaver.MethodDeclarationLineNumber";
  287. public String getNameString() {
  288. return AttributeName;
  289. }
  290. private int lineNumber;
  291. // AV: added in 1.5 M3 thus handling cases where we don't have that information
  292. private int offset;
  293. public MethodDeclarationLineNumberAttribute(int line, int offset) {
  294. this.lineNumber = line;
  295. this.offset = offset;
  296. }
  297. public int getLineNumber() { return lineNumber; }
  298. public int getOffset() { return offset; }
  299. public void write(DataOutputStream s) throws IOException {
  300. s.writeInt(lineNumber);
  301. s.writeInt(offset);
  302. }
  303. public static MethodDeclarationLineNumberAttribute read(VersionedDataInputStream s) throws IOException {
  304. int line = s.readInt();
  305. int offset = 0;
  306. if (s.available()>0) {
  307. offset = s.readInt();
  308. }
  309. return new MethodDeclarationLineNumberAttribute(line, offset);
  310. }
  311. public String toString() {
  312. return AttributeName + ": " + lineNumber + ":" + offset;
  313. }
  314. }
  315. public static class PointcutDeclarationAttribute extends AjAttribute {
  316. public static final String AttributeName = "org.aspectj.weaver.PointcutDeclaration";
  317. public String getNameString() {
  318. return AttributeName;
  319. }
  320. private ResolvedPointcutDefinition pointcutDef;
  321. public PointcutDeclarationAttribute(ResolvedPointcutDefinition pointcutDef) {
  322. this.pointcutDef = pointcutDef;
  323. }
  324. public void write(DataOutputStream s) throws IOException {
  325. pointcutDef.write(s);
  326. }
  327. public ResolvedPointcutDefinition reify() {
  328. return pointcutDef;
  329. }
  330. }
  331. public static class DeclareAttribute extends AjAttribute {
  332. public static final String AttributeName = "org.aspectj.weaver.Declare";
  333. public String getNameString() {
  334. return AttributeName;
  335. }
  336. private Declare declare;
  337. public DeclareAttribute(Declare declare) {
  338. this.declare = declare;
  339. }
  340. public void write(DataOutputStream s) throws IOException {
  341. declare.write(s);
  342. }
  343. public Declare getDeclare() {
  344. return declare;
  345. }
  346. }
  347. public static class AdviceAttribute extends AjAttribute {
  348. public static final String AttributeName = "org.aspectj.weaver.Advice";
  349. public String getNameString() {
  350. return AttributeName;
  351. }
  352. private AdviceKind kind;
  353. private Pointcut pointcut;
  354. private int extraParameterFlags;
  355. private int start;
  356. private int end;
  357. private ISourceContext sourceContext;
  358. // these are only used by around advice
  359. private boolean proceedInInners;
  360. private ResolvedMember[] proceedCallSignatures; // size == # of proceed calls in body
  361. private boolean[] formalsUnchangedToProceed; // size == formals.size
  362. private UnresolvedType[] declaredExceptions;
  363. /**
  364. * @param lexicalPosition must be greater than the lexicalPosition
  365. * of any advice declared before this one in an aspect, otherwise,
  366. * it can be any value.
  367. */
  368. public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags,
  369. int start, int end, ISourceContext sourceContext) {
  370. this.kind = kind;
  371. this.pointcut = pointcut;
  372. this.extraParameterFlags = extraArgumentFlags;
  373. this.start = start;
  374. this.end = end;
  375. this.sourceContext = sourceContext;
  376. //XXX put this back when testing works better (or fails better)
  377. //if (kind == AdviceKind.Around) throw new IllegalArgumentException("not for around");
  378. }
  379. public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags,
  380. int start, int end, ISourceContext sourceContext,
  381. boolean proceedInInners, ResolvedMember[] proceedCallSignatures,
  382. boolean[] formalsUnchangedToProceed, UnresolvedType[] declaredExceptions) {
  383. this.kind = kind;
  384. this.pointcut = pointcut;
  385. this.extraParameterFlags = extraArgumentFlags;
  386. this.start = start;
  387. this.end = end;
  388. this.sourceContext = sourceContext;
  389. if (kind != AdviceKind.Around) throw new IllegalArgumentException("only for around");
  390. this.proceedInInners = proceedInInners;
  391. this.proceedCallSignatures = proceedCallSignatures;
  392. this.formalsUnchangedToProceed = formalsUnchangedToProceed;
  393. this.declaredExceptions = declaredExceptions;
  394. }
  395. public static AdviceAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  396. AdviceKind kind = AdviceKind.read(s);
  397. if (kind == AdviceKind.Around) {
  398. return new AdviceAttribute(
  399. kind,
  400. Pointcut.read(s, context),
  401. s.readByte(),
  402. s.readInt(), s.readInt(), context,
  403. s.readBoolean(),
  404. ResolvedMemberImpl.readResolvedMemberArray(s, context),
  405. FileUtil.readBooleanArray(s),
  406. UnresolvedType.readArray(s));
  407. } else {
  408. return new AdviceAttribute(
  409. kind,
  410. Pointcut.read(s, context),
  411. s.readByte(),
  412. s.readInt(), s.readInt(), context);
  413. }
  414. }
  415. public void write(DataOutputStream s) throws IOException {
  416. kind.write(s);
  417. pointcut.write(s);
  418. s.writeByte(extraParameterFlags);
  419. s.writeInt(start);
  420. s.writeInt(end);
  421. if (kind == AdviceKind.Around) {
  422. s.writeBoolean(proceedInInners);
  423. ResolvedMemberImpl.writeArray(proceedCallSignatures, s);
  424. FileUtil.writeBooleanArray(formalsUnchangedToProceed, s);
  425. UnresolvedType.writeArray(declaredExceptions, s);
  426. }
  427. }
  428. public Advice reify(Member signature, World world) {
  429. return world.createAdviceMunger(this, pointcut, signature);
  430. }
  431. public String toString() {
  432. return "AdviceAttribute(" + kind + ", " + pointcut + ", " +
  433. extraParameterFlags + ", " + start+")";
  434. }
  435. public int getExtraParameterFlags() {
  436. return extraParameterFlags;
  437. }
  438. public AdviceKind getKind() {
  439. return kind;
  440. }
  441. public Pointcut getPointcut() {
  442. return pointcut;
  443. }
  444. public UnresolvedType[] getDeclaredExceptions() {
  445. return declaredExceptions;
  446. }
  447. public boolean[] getFormalsUnchangedToProceed() {
  448. return formalsUnchangedToProceed;
  449. }
  450. public ResolvedMember[] getProceedCallSignatures() {
  451. return proceedCallSignatures;
  452. }
  453. public boolean isProceedInInners() {
  454. return proceedInInners;
  455. }
  456. public int getEnd() {
  457. return end;
  458. }
  459. public ISourceContext getSourceContext() {
  460. return sourceContext;
  461. }
  462. public int getStart() {
  463. return start;
  464. }
  465. }
  466. public static class Aspect extends AjAttribute {
  467. public static final String AttributeName = "org.aspectj.weaver.Aspect";
  468. public String getNameString() {
  469. return AttributeName;
  470. }
  471. private PerClause perClause;
  472. private IScope resolutionScope;
  473. public Aspect(PerClause perClause) {
  474. this.perClause = perClause;
  475. }
  476. public PerClause reify(ResolvedType inAspect) {
  477. //XXXperClause.concretize(inAspect);
  478. return perClause;
  479. }
  480. public PerClause reifyFromAtAspectJ(ResolvedType inAspect) {
  481. perClause.resolve(resolutionScope);
  482. return perClause;
  483. }
  484. public void write(DataOutputStream s) throws IOException {
  485. perClause.write(s);
  486. }
  487. public void setResolutionScope(IScope binding) {
  488. this.resolutionScope = binding;
  489. }
  490. }
  491. public static class PrivilegedAttribute extends AjAttribute {
  492. public static final String AttributeName = "org.aspectj.weaver.Privileged";
  493. public String getNameString() {
  494. return AttributeName;
  495. }
  496. private ResolvedMember[] accessedMembers;
  497. public PrivilegedAttribute(ResolvedMember[] accessedMembers) {
  498. this.accessedMembers = accessedMembers;
  499. }
  500. public void write(DataOutputStream s) throws IOException {
  501. ResolvedMemberImpl.writeArray(accessedMembers, s);
  502. }
  503. public ResolvedMember[] getAccessedMembers() {
  504. return accessedMembers;
  505. }
  506. public static PrivilegedAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  507. return new PrivilegedAttribute(ResolvedMemberImpl.readResolvedMemberArray(s, context));
  508. }
  509. }
  510. public static class EffectiveSignatureAttribute extends AjAttribute {
  511. public static final String AttributeName = "org.aspectj.weaver.EffectiveSignature";
  512. public String getNameString() {
  513. return AttributeName;
  514. }
  515. private ResolvedMember effectiveSignature;
  516. private Shadow.Kind shadowKind;
  517. private boolean weaveBody;
  518. public EffectiveSignatureAttribute(ResolvedMember effectiveSignature, Shadow.Kind shadowKind, boolean weaveBody) {
  519. this.effectiveSignature = effectiveSignature;
  520. this.shadowKind = shadowKind;
  521. this.weaveBody = weaveBody;
  522. }
  523. public void write(DataOutputStream s) throws IOException {
  524. effectiveSignature.write(s);
  525. shadowKind.write(s);
  526. s.writeBoolean(weaveBody);
  527. }
  528. public static EffectiveSignatureAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  529. return new EffectiveSignatureAttribute(
  530. ResolvedMemberImpl.readResolvedMember(s, context),
  531. Shadow.Kind.read(s),
  532. s.readBoolean());
  533. }
  534. public ResolvedMember getEffectiveSignature() {
  535. return effectiveSignature;
  536. }
  537. public String toString() {
  538. return "EffectiveSignatureAttribute(" + effectiveSignature + ", " + shadowKind + ")";
  539. }
  540. public Shadow.Kind getShadowKind() {
  541. return shadowKind;
  542. }
  543. public boolean isWeaveBody() {
  544. return weaveBody;
  545. }
  546. }
  547. }