Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

AspectDeclaration.java 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  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 Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * Xerox/PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.ajdt.internal.compiler.ast;
  13. import java.io.*;
  14. import java.lang.reflect.Modifier;
  15. import org.apache.bcel.classfile.AccessFlags;
  16. import org.aspectj.ajdt.internal.compiler.lookup.*;
  17. import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
  18. import org.aspectj.weaver.*;
  19. import org.aspectj.weaver.AjAttribute;
  20. import org.aspectj.weaver.patterns.*;
  21. import org.eclipse.jdt.internal.compiler.*;
  22. import org.eclipse.jdt.internal.compiler.ast.*;
  23. import org.eclipse.jdt.internal.compiler.codegen.*;
  24. import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
  25. import org.eclipse.jdt.internal.compiler.lookup.*;
  26. import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
  27. // making all aspects member types avoids a nasty hierarchy pain
  28. public class AspectDeclaration extends MemberTypeDeclaration {
  29. //public IAjDeclaration[] ajDeclarations;
  30. private AjAttribute.Aspect aspectAttribute;
  31. public PerClause perClause;
  32. public ResolvedMember aspectOfMethod;
  33. public ResolvedMember hasAspectMethod;
  34. public boolean isPrivileged;
  35. public EclipseObjectType typeX;
  36. public EclipseWorld world; //??? should use this consistently
  37. // for better error messages in 1.0 to 1.1 transition
  38. public TypePattern dominatesPattern;
  39. public AspectDeclaration(CompilationResult compilationResult) {
  40. super(compilationResult);
  41. //perClause = new PerSingleton();
  42. }
  43. public boolean isAbstract() {
  44. return (modifiers & AccAbstract) != 0;
  45. }
  46. public void resolve() {
  47. if (binding == null || ignoreFurtherInvestigation) {
  48. ignoreFurtherInvestigation = true;
  49. return;
  50. }
  51. if (typeX != null) typeX.checkPointcutDeclarations();
  52. super.resolve();
  53. }
  54. public void checkSpec(ClassScope scope) {
  55. if (ignoreFurtherInvestigation) return;
  56. if (dominatesPattern != null) {
  57. scope.problemReporter().signalError(
  58. dominatesPattern.getStart(), dominatesPattern.getEnd(),
  59. "dominates has changed for 1.1, use 'declare dominates: " +
  60. new String(this.name) + ", " + dominatesPattern.toString() + ";' " +
  61. "in the body of the aspect instead");
  62. }
  63. if (!isAbstract()) {
  64. MethodBinding[] methods = binding.methods();
  65. for (int i=0, len = methods.length; i < len; i++) {
  66. MethodBinding m = methods[i];
  67. if (m.isConstructor()) {
  68. // this make all constructors in aspects invisible and thus uncallable
  69. //XXX this only works for aspects that come from source
  70. methods[i] = new MethodBinding(m, binding) {
  71. public boolean canBeSeenBy(
  72. InvocationSite invocationSite,
  73. Scope scope) {
  74. return false;
  75. }
  76. };
  77. if (m.parameters != null && m.parameters.length != 0) {
  78. scope.problemReporter().signalError(m.sourceStart(), m.sourceEnd(),
  79. "only zero-argument constructors allowed in concrete aspect");
  80. }
  81. }
  82. }
  83. }
  84. if (this.enclosingType != null) {
  85. if (!Modifier.isStatic(modifiers)) {
  86. scope.problemReporter().signalError(sourceStart, sourceEnd,
  87. "inner aspects must be static");
  88. ignoreFurtherInvestigation = true;
  89. return;
  90. }
  91. }
  92. EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(scope);
  93. ResolvedTypeX myType = world.fromEclipse(binding);
  94. ResolvedTypeX superType = myType.getSuperclass().resolve(world);
  95. // can't be Serializable/Cloneable unless -XserializableAspects
  96. if (!world.buildManager.buildConfig.isXserializableAspects()) {
  97. if (world.resolve(TypeX.SERIALIZABLE).isAssignableFrom(myType)) {
  98. scope.problemReporter().signalError(sourceStart, sourceEnd,
  99. "aspects may not implement Serializable");
  100. ignoreFurtherInvestigation = true;
  101. return;
  102. }
  103. if (world.resolve(TypeX.CLONEABLE).isAssignableFrom(myType)) {
  104. scope.problemReporter().signalError(sourceStart, sourceEnd,
  105. "aspects may not implement Cloneable");
  106. ignoreFurtherInvestigation = true;
  107. return;
  108. }
  109. }
  110. if (superType.isAspect()) {
  111. if (!superType.isAbstract()) {
  112. scope.problemReporter().signalError(sourceStart, sourceEnd,
  113. "can not extend a concrete aspect");
  114. ignoreFurtherInvestigation = true;
  115. return;
  116. }
  117. }
  118. }
  119. public void generateCode(ClassFile enclosingClassFile) {
  120. if (ignoreFurtherInvestigation) {
  121. if (binding == null)
  122. return;
  123. ClassFile.createProblemType(
  124. this,
  125. scope.referenceCompilationUnit().compilationResult);
  126. return;
  127. }
  128. // make me and my binding public
  129. this.modifiers = AstUtil.makePublic(this.modifiers);
  130. this.binding.modifiers = AstUtil.makePublic(this.binding.modifiers);
  131. if (!isAbstract()) {
  132. if (perClause == null) {
  133. // we've already produced an error for this
  134. } else if (perClause.getKind() == PerClause.SINGLETON) {
  135. binding.addField(world.makeFieldBinding(AjcMemberMaker.perSingletonField(
  136. typeX)));
  137. methods[0] = new AspectClinit((Clinit)methods[0], compilationResult);
  138. } else if (perClause.getKind() == PerClause.PERCFLOW) {
  139. binding.addField(
  140. world.makeFieldBinding(
  141. AjcMemberMaker.perCflowField(
  142. typeX)));
  143. methods[0] = new AspectClinit((Clinit)methods[0], compilationResult);
  144. } else if (perClause.getKind() == PerClause.PEROBJECT) {
  145. // binding.addField(
  146. // world.makeFieldBinding(
  147. // AjcMemberMaker.perCflowField(
  148. // typeX)));
  149. } else {
  150. throw new RuntimeException("unimplemented");
  151. }
  152. }
  153. if (EclipseWorld.DEBUG) System.out.println(toString(0));
  154. super.generateCode(enclosingClassFile);
  155. }
  156. public boolean needClassInitMethod() {
  157. return true;
  158. }
  159. protected void generateAttributes(ClassFile classFile) {
  160. if (!isAbstract()) generatePerSupportMembers(classFile);
  161. classFile.extraAttributes.add(
  162. new EclipseAttributeAdapter(new AjAttribute.Aspect(perClause)));
  163. if (binding.privilegedHandler != null) {
  164. ResolvedMember[] members = ((PrivilegedHandler)binding.privilegedHandler).getMembers();
  165. classFile.extraAttributes.add(
  166. new EclipseAttributeAdapter(new AjAttribute.PrivilegedAttribute(members)));
  167. }
  168. //XXX need to get this attribute on anyone with a pointcut for good errors
  169. classFile.extraAttributes.add(
  170. new EclipseAttributeAdapter(new AjAttribute.SourceContextAttribute(
  171. new String(compilationResult().getFileName()),
  172. compilationResult().lineSeparatorPositions)));
  173. super.generateAttributes(classFile);
  174. }
  175. private void generatePerSupportMembers(ClassFile classFile) {
  176. if (isAbstract()) return;
  177. //XXX otherwise we need to have this (error handling?)
  178. if (aspectOfMethod == null) return;
  179. if (perClause == null) {
  180. System.err.println("has null perClause: " + this);
  181. return;
  182. }
  183. EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  184. if (perClause.getKind() == PerClause.SINGLETON) {
  185. generatePerSingletonAspectOfMethod(classFile);
  186. generatePerSingletonHasAspectMethod(classFile);
  187. generatePerSingletonAjcClinitMethod(classFile);
  188. } else if (perClause.getKind() == PerClause.PERCFLOW) {
  189. generatePerCflowAspectOfMethod(classFile);
  190. generatePerCflowHasAspectMethod(classFile);
  191. generatePerCflowPushMethod(classFile);
  192. generatePerCflowAjcClinitMethod(classFile);
  193. } else if (perClause.getKind() == PerClause.PEROBJECT) {
  194. TypeBinding interfaceType =
  195. generatePerObjectInterface(classFile);
  196. world.addTypeBinding(interfaceType);
  197. generatePerObjectAspectOfMethod(classFile, interfaceType);
  198. generatePerObjectHasAspectMethod(classFile, interfaceType);
  199. generatePerObjectBindMethod(classFile, interfaceType);
  200. } else {
  201. throw new RuntimeException("unimplemented");
  202. }
  203. }
  204. private static interface BodyGenerator {
  205. public void generate(CodeStream codeStream);
  206. }
  207. private void generateMethod(ClassFile classFile, ResolvedMember member, BodyGenerator gen) {
  208. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  209. generateMethod(classFile, world.makeMethodBinding(member), gen);
  210. }
  211. private void generateMethod(ClassFile classFile, MethodBinding methodBinding, BodyGenerator gen) {
  212. EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  213. classFile.generateMethodInfoHeader(methodBinding);
  214. int methodAttributeOffset = classFile.contentsOffset;
  215. int attributeNumber = classFile.generateMethodInfoAttribute(methodBinding, AstUtil.getAjSyntheticAttribute());
  216. int codeAttributeOffset = classFile.contentsOffset;
  217. classFile.generateCodeAttributeHeader();
  218. CodeStream codeStream = classFile.codeStream;
  219. codeStream.init(classFile);
  220. codeStream.initializeMaxLocals(methodBinding);
  221. // body starts here
  222. gen.generate(codeStream);
  223. // body ends here
  224. classFile.completeCodeAttribute(codeAttributeOffset);
  225. attributeNumber++;
  226. classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
  227. }
  228. private void generatePerCflowAspectOfMethod(
  229. ClassFile classFile)
  230. {
  231. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  232. generateMethod(classFile, aspectOfMethod, new BodyGenerator() {
  233. public void generate(CodeStream codeStream) {
  234. // body starts here
  235. codeStream.getstatic(
  236. world.makeFieldBinding(
  237. AjcMemberMaker.perCflowField(
  238. typeX)));
  239. codeStream.invokevirtual(world.makeMethodBindingForCall(
  240. AjcMemberMaker.cflowStackPeekInstance()));
  241. codeStream.checkcast(binding);
  242. codeStream.areturn();
  243. // body ends here
  244. }});
  245. }
  246. private void generatePerCflowHasAspectMethod(ClassFile classFile) {
  247. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  248. generateMethod(classFile, hasAspectMethod, new BodyGenerator() {
  249. public void generate(CodeStream codeStream) {
  250. // body starts here
  251. codeStream.getstatic(
  252. world.makeFieldBinding(
  253. AjcMemberMaker.perCflowField(
  254. typeX)));
  255. codeStream.invokevirtual(world.makeMethodBindingForCall(
  256. AjcMemberMaker.cflowStackIsValid()));
  257. codeStream.ireturn();
  258. // body ends here
  259. }});
  260. }
  261. private void generatePerCflowPushMethod(
  262. ClassFile classFile)
  263. {
  264. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  265. generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.perCflowPush(
  266. world.fromBinding(binding))),
  267. new BodyGenerator() {
  268. public void generate(CodeStream codeStream) {
  269. // body starts here
  270. codeStream.getstatic(
  271. world.makeFieldBinding(
  272. AjcMemberMaker.perCflowField(
  273. typeX)));
  274. codeStream.new_(binding);
  275. codeStream.dup();
  276. codeStream.invokespecial(
  277. new MethodBinding(0, "<init>".toCharArray(),
  278. BaseTypes.VoidBinding, new TypeBinding[0],
  279. new ReferenceBinding[0], binding));
  280. codeStream.invokevirtual(world.makeMethodBindingForCall(
  281. AjcMemberMaker.cflowStackPushInstance()));
  282. codeStream.return_();
  283. // body ends here
  284. }});
  285. }
  286. private void generatePerCflowAjcClinitMethod(
  287. ClassFile classFile)
  288. {
  289. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  290. generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.ajcClinitMethod(
  291. world.fromBinding(binding))),
  292. new BodyGenerator() {
  293. public void generate(CodeStream codeStream) {
  294. // body starts here
  295. codeStream.new_(world.makeTypeBinding(AjcMemberMaker.CFLOW_STACK_TYPE));
  296. codeStream.dup();
  297. codeStream.invokespecial(world.makeMethodBindingForCall(AjcMemberMaker.cflowStackInit()));
  298. codeStream.putstatic(
  299. world.makeFieldBinding(
  300. AjcMemberMaker.perCflowField(
  301. typeX)));
  302. codeStream.return_();
  303. // body ends here
  304. }});
  305. }
  306. private TypeBinding generatePerObjectInterface(
  307. ClassFile classFile)
  308. {
  309. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  310. TypeX interfaceTypeX =
  311. AjcMemberMaker.perObjectInterfaceType(typeX);
  312. HelperInterfaceBinding interfaceType =
  313. new HelperInterfaceBinding(this.binding, interfaceTypeX);
  314. world.addTypeBinding(interfaceType);
  315. interfaceType.addMethod(world, AjcMemberMaker.perObjectInterfaceGet(typeX));
  316. interfaceType.addMethod(world, AjcMemberMaker.perObjectInterfaceSet(typeX));
  317. interfaceType.generateClass(compilationResult, classFile);
  318. return interfaceType;
  319. }
  320. private void generatePerObjectAspectOfMethod(
  321. ClassFile classFile,
  322. final TypeBinding interfaceType)
  323. {
  324. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  325. generateMethod(classFile, aspectOfMethod, new BodyGenerator() {
  326. public void generate(CodeStream codeStream) {
  327. // body starts here
  328. Label wrongType = new Label(codeStream);
  329. Label popWrongType = new Label(codeStream);
  330. codeStream.aload_0();
  331. codeStream.instance_of(interfaceType);
  332. codeStream.ifeq(wrongType);
  333. codeStream.aload_0();
  334. codeStream.checkcast(interfaceType);
  335. codeStream.invokeinterface(world.makeMethodBindingForCall(
  336. AjcMemberMaker.perObjectInterfaceGet(typeX)));
  337. codeStream.dup();
  338. codeStream.ifnull(popWrongType);
  339. codeStream.areturn();
  340. popWrongType.place();
  341. codeStream.pop();
  342. wrongType.place();
  343. codeStream.new_(world.makeTypeBinding(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION));
  344. codeStream.dup();
  345. codeStream.invokespecial(world.makeMethodBindingForCall(
  346. AjcMemberMaker.noAspectBoundExceptionInit()
  347. ));
  348. codeStream.athrow();
  349. // body ends here
  350. }});
  351. }
  352. private void generatePerObjectHasAspectMethod(ClassFile classFile,
  353. final TypeBinding interfaceType) {
  354. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  355. generateMethod(classFile, hasAspectMethod, new BodyGenerator() {
  356. public void generate(CodeStream codeStream) {
  357. // body starts here
  358. Label wrongType = new Label(codeStream);
  359. codeStream.aload_0();
  360. codeStream.instance_of(interfaceType);
  361. codeStream.ifeq(wrongType);
  362. codeStream.aload_0();
  363. codeStream.checkcast(interfaceType);
  364. codeStream.invokeinterface(world.makeMethodBindingForCall(
  365. AjcMemberMaker.perObjectInterfaceGet(typeX)));
  366. codeStream.ifnull(wrongType);
  367. codeStream.iconst_1();
  368. codeStream.ireturn();
  369. wrongType.place();
  370. codeStream.iconst_0();
  371. codeStream.ireturn();
  372. // body ends here
  373. }});
  374. }
  375. private void generatePerObjectBindMethod(
  376. ClassFile classFile,
  377. final TypeBinding interfaceType)
  378. {
  379. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  380. generateMethod(classFile, AjcMemberMaker.perObjectBind(world.fromBinding(binding)),
  381. new BodyGenerator() {
  382. public void generate(CodeStream codeStream) {
  383. // body starts here
  384. Label wrongType = new Label(codeStream);
  385. codeStream.aload_0();
  386. codeStream.instance_of(interfaceType);
  387. codeStream.ifeq(wrongType); //XXX this case might call for screaming
  388. codeStream.aload_0();
  389. codeStream.checkcast(interfaceType);
  390. codeStream.invokeinterface(world.makeMethodBindingForCall(
  391. AjcMemberMaker.perObjectInterfaceGet(typeX)));
  392. //XXX should do a check for null here and throw a NoAspectBound
  393. codeStream.ifnonnull(wrongType);
  394. codeStream.aload_0();
  395. codeStream.checkcast(interfaceType);
  396. codeStream.new_(binding);
  397. codeStream.dup();
  398. codeStream.invokespecial(
  399. new MethodBinding(0, "<init>".toCharArray(),
  400. BaseTypes.VoidBinding, new TypeBinding[0],
  401. new ReferenceBinding[0], binding));
  402. codeStream.invokeinterface(world.makeMethodBindingForCall(
  403. AjcMemberMaker.perObjectInterfaceSet(typeX)));
  404. wrongType.place();
  405. codeStream.return_();
  406. // body ends here
  407. }});
  408. }
  409. private void generatePerSingletonAspectOfMethod(ClassFile classFile) {
  410. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  411. generateMethod(classFile, aspectOfMethod, new BodyGenerator() {
  412. public void generate(CodeStream codeStream) {
  413. // body starts here
  414. codeStream.getstatic(world.makeFieldBinding(AjcMemberMaker.perSingletonField(
  415. typeX)));
  416. codeStream.areturn();
  417. // body ends here
  418. }});
  419. }
  420. private void generatePerSingletonHasAspectMethod(ClassFile classFile) {
  421. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  422. generateMethod(classFile, hasAspectMethod, new BodyGenerator() {
  423. public void generate(CodeStream codeStream) {
  424. // body starts here
  425. codeStream.getstatic(world.makeFieldBinding(AjcMemberMaker.perSingletonField(
  426. typeX)));
  427. Label isNull = new Label(codeStream);
  428. codeStream.ifnull(isNull);
  429. codeStream.iconst_1();
  430. codeStream.ireturn();
  431. isNull.place();
  432. codeStream.iconst_0();
  433. codeStream.ireturn();
  434. // body ends here
  435. }});
  436. }
  437. private void generatePerSingletonAjcClinitMethod(
  438. ClassFile classFile)
  439. {
  440. final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
  441. generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.ajcClinitMethod(
  442. world.fromBinding(binding))),
  443. new BodyGenerator() {
  444. public void generate(CodeStream codeStream) {
  445. // body starts here
  446. codeStream.new_(binding);
  447. codeStream.dup();
  448. codeStream.invokespecial(
  449. new MethodBinding(0, "<init>".toCharArray(),
  450. BaseTypes.VoidBinding, new TypeBinding[0],
  451. new ReferenceBinding[0], binding));
  452. codeStream.putstatic(
  453. world.makeFieldBinding(
  454. AjcMemberMaker.perSingletonField(
  455. typeX)));
  456. codeStream.return_();
  457. // body ends here
  458. }});
  459. }
  460. private PerClause.Kind lookupPerClauseKind(ReferenceBinding binding) {
  461. if (binding instanceof SourceTypeBinding) {
  462. SourceTypeBinding sourceSc = (SourceTypeBinding)binding;
  463. if (sourceSc.scope.referenceContext instanceof AspectDeclaration) {
  464. PerClause perClause = ((AspectDeclaration)sourceSc.scope.referenceContext).perClause;
  465. if (perClause == null) return lookupPerClauseKind(binding.superclass());
  466. else return perClause.getKind();
  467. } else {
  468. return null;
  469. }
  470. } else {
  471. //XXX need to handle this too
  472. return null;
  473. }
  474. }
  475. private void buildPerClause(ClassScope scope) {
  476. EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(scope);
  477. if (perClause == null) {
  478. PerClause.Kind kind = lookupPerClauseKind(binding.superclass);
  479. if (kind == null) {
  480. perClause = new PerSingleton();
  481. } else {
  482. perClause = new PerFromSuper(kind);
  483. }
  484. }
  485. //perClause.concretize(world.fromEclipse(binding));
  486. aspectAttribute = new AjAttribute.Aspect(perClause);
  487. if (ignoreFurtherInvestigation) return; //???
  488. if (!isAbstract()) {
  489. if (perClause.getKind() == PerClause.SINGLETON) {
  490. aspectOfMethod = AjcMemberMaker.perSingletonAspectOfMethod(typeX);
  491. hasAspectMethod = AjcMemberMaker.perSingletonHasAspectMethod(typeX);
  492. } else if (perClause.getKind() == PerClause.PERCFLOW) {
  493. aspectOfMethod = AjcMemberMaker.perCflowAspectOfMethod(typeX);
  494. hasAspectMethod = AjcMemberMaker.perCflowHasAspectMethod(typeX);
  495. } else if (perClause.getKind() == PerClause.PEROBJECT) {
  496. aspectOfMethod = AjcMemberMaker.perObjectAspectOfMethod(typeX);
  497. hasAspectMethod = AjcMemberMaker.perObjectHasAspectMethod(typeX);
  498. } else {
  499. throw new RuntimeException("bad per clause: " + perClause);
  500. }
  501. binding.addMethod(world.makeMethodBinding(aspectOfMethod));
  502. binding.addMethod(world.makeMethodBinding(hasAspectMethod));
  503. }
  504. resolvePerClause(); //XXX might be too soon for some error checking
  505. }
  506. private PerClause resolvePerClause() {
  507. EclipseScope iscope = new EclipseScope(new FormalBinding[0], scope);
  508. perClause.resolve(iscope);
  509. return perClause;
  510. }
  511. public void buildInterTypeAndPerClause(ClassScope classScope) {
  512. checkSpec(classScope);
  513. if (ignoreFurtherInvestigation) return;
  514. world = EclipseWorld.fromScopeLookupEnvironment(scope);
  515. typeX = (EclipseObjectType)world.fromEclipse(binding);
  516. if (isPrivileged) {
  517. binding.privilegedHandler = new PrivilegedHandler(this);
  518. }
  519. CrosscuttingMembers xcut = new CrosscuttingMembers(typeX);
  520. typeX.crosscuttingMembers = xcut;
  521. //XXXxcut.setPerClause(buildPerClause(scope));
  522. buildPerClause(scope);
  523. if (methods != null) {
  524. for (int i = 0; i < methods.length; i++) {
  525. if (methods[i] instanceof InterTypeDeclaration) {
  526. ((InterTypeDeclaration)methods[i]).build(classScope, xcut);
  527. } else if (methods[i] instanceof DeclareDeclaration) {
  528. ((DeclareDeclaration)methods[i]).build(classScope, xcut);
  529. }
  530. }
  531. }
  532. world.getCrosscuttingMembersSet().addOrReplaceAspect(typeX);
  533. }
  534. public String toString(int tab) {
  535. return tabString(tab) + toStringHeader() + toStringBody(tab);
  536. }
  537. public String toStringBody(int tab) {
  538. String s = " {"; //$NON-NLS-1$
  539. if (memberTypes != null) {
  540. for (int i = 0; i < memberTypes.length; i++) {
  541. if (memberTypes[i] != null) {
  542. s += "\n" + memberTypes[i].toString(tab + 1); //$NON-NLS-1$
  543. }
  544. }
  545. }
  546. if (fields != null) {
  547. for (int fieldI = 0; fieldI < fields.length; fieldI++) {
  548. if (fields[fieldI] != null) {
  549. s += "\n" + fields[fieldI].toString(tab + 1); //$NON-NLS-1$
  550. if (fields[fieldI].isField())
  551. s += ";"; //$NON-NLS-1$
  552. }
  553. }
  554. }
  555. if (methods != null) {
  556. for (int i = 0; i < methods.length; i++) {
  557. if (methods[i] != null) {
  558. s += "\n" + methods[i].toString(tab + 1); //$NON-NLS-1$
  559. }
  560. }
  561. }
  562. s += "\n" + tabString(tab) + "}"; //$NON-NLS-2$ //$NON-NLS-1$
  563. return s;
  564. }
  565. public String toStringHeader() {
  566. String s = ""; //$NON-NLS-1$
  567. if (modifiers != AccDefault) {
  568. s += modifiersString(modifiers);
  569. }
  570. s += "aspect " + new String(name);//$NON-NLS-1$ //$NON-NLS-2$
  571. if (superclass != null)
  572. s += " extends " + superclass.toString(0); //$NON-NLS-1$
  573. if (superInterfaces != null && superInterfaces.length > 0) {
  574. s += (isInterface() ? " extends " : " implements ");//$NON-NLS-2$ //$NON-NLS-1$
  575. for (int i = 0; i < superInterfaces.length; i++) {
  576. s += superInterfaces[i].toString(0);
  577. if (i != superInterfaces.length - 1)
  578. s += ", "; //$NON-NLS-1$
  579. };
  580. };
  581. return s;
  582. }
  583. }