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.

AjLookupEnvironment.java 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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.lookup;
  13. import java.util.*;
  14. import org.aspectj.ajdt.internal.compiler.ast.*;
  15. import org.aspectj.bridge.MessageUtil;
  16. import org.aspectj.weaver.*;
  17. import org.aspectj.weaver.patterns.*;
  18. import org.eclipse.jdt.internal.compiler.ast.*;
  19. import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
  20. import org.eclipse.jdt.internal.compiler.impl.*;
  21. import org.eclipse.jdt.internal.compiler.lookup.*;
  22. import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
  23. public class AjLookupEnvironment extends LookupEnvironment {
  24. public EclipseWorld world = null;
  25. public AjLookupEnvironment(
  26. ITypeRequestor typeRequestor,
  27. CompilerOptions options,
  28. ProblemReporter problemReporter,
  29. INameEnvironment nameEnvironment) {
  30. super(typeRequestor, options, problemReporter, nameEnvironment);
  31. }
  32. //XXX figure out if we can do this through super or not
  33. //XXX otherwise duplicates some of super's code
  34. public void completeTypeBindings() {
  35. stepCompleted = BUILD_TYPE_HIERARCHY;
  36. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  37. units[i].scope.checkAndSetImports();
  38. }
  39. stepCompleted = CHECK_AND_SET_IMPORTS;
  40. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  41. units[i].scope.connectTypeHierarchy();
  42. }
  43. stepCompleted = CONNECT_TYPE_HIERARCHY;
  44. // collect inter-type declarations as well
  45. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  46. units[i].scope.buildFieldsAndMethods();
  47. }
  48. // need to build inter-type declarations for all AspectDeclarations at this point
  49. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  50. SourceTypeBinding[] b = units[i].scope.topLevelTypes;
  51. for (int j = 0; j < b.length; j++) {
  52. buildInterTypeAndPerClause(b[j].scope);
  53. }
  54. }
  55. //??? do we need a new stepCompleted
  56. // now do weaving
  57. Collection typeMungers = world.getTypeMungers();
  58. Collection declareParents = world.getDeclareParents();
  59. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  60. weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents);
  61. units[i] = null; // release unnecessary reference to the parsed unit
  62. }
  63. stepCompleted = BUILD_FIELDS_AND_METHODS;
  64. lastCompletedUnitIndex = lastUnitIndex;
  65. }
  66. private void buildInterTypeAndPerClause(ClassScope s) {
  67. TypeDeclaration dec = s.referenceContext;
  68. if (dec instanceof AspectDeclaration) {
  69. ((AspectDeclaration)dec).buildInterTypeAndPerClause(s);
  70. }
  71. SourceTypeBinding sourceType = s.referenceContext.binding;
  72. ReferenceBinding[] memberTypes = sourceType.memberTypes;
  73. for (int i = 0, length = memberTypes.length; i < length; i++) {
  74. buildInterTypeAndPerClause(((SourceTypeBinding) memberTypes[i]).scope);
  75. }
  76. }
  77. private void weaveInterTypeDeclarations(CompilationUnitScope unit, Collection typeMungers, Collection declareParents) {
  78. for (int i = 0, length = unit.topLevelTypes.length; i < length; i++)
  79. weaveInterTypeDeclarations(unit.topLevelTypes[i].scope, typeMungers, declareParents);
  80. //System.err.println("done with inter types");
  81. }
  82. private void weaveInterTypeDeclarations(ClassScope scope, Collection typeMungers, Collection declareParents) {
  83. //System.err.println("weaving: " + scope);
  84. SourceTypeBinding sourceType = scope.referenceContext.binding;
  85. ResolvedTypeX onType = world.fromEclipse(sourceType);
  86. for (Iterator i = declareParents.iterator(); i.hasNext();) {
  87. doDeclareParents((DeclareParents)i.next(), scope);
  88. }
  89. for (Iterator i = typeMungers.iterator(); i.hasNext();) {
  90. EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
  91. //System.out.println("weaving: " + munger);
  92. //if (munger.match(scope))
  93. if (munger.matches(onType)) {
  94. onType.addInterTypeMunger(munger);
  95. }
  96. }
  97. for (Iterator i = onType.getInterTypeMungers().iterator(); i.hasNext();) {
  98. EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
  99. munger.munge(scope);
  100. }
  101. ReferenceBinding[] memberTypes = sourceType.memberTypes;
  102. for (int i = 0, length = memberTypes.length; i < length; i++) {
  103. weaveInterTypeDeclarations(((SourceTypeBinding) memberTypes[i]).scope, typeMungers, declareParents);
  104. }
  105. }
  106. private void doDeclareParents(DeclareParents declareParents, ClassScope scope) {
  107. if (declareParents.match(world.fromEclipse(scope.referenceContext.binding))) {
  108. TypePatternList l = declareParents.getParents();
  109. for (int i=0, len=l.size(); i < len; i++) {
  110. addParent(declareParents, scope, l.get(i));
  111. }
  112. }
  113. }
  114. private void addParent(DeclareParents declareParents, ClassScope scope, TypePattern typePattern) {
  115. SourceTypeBinding sourceType = scope.referenceContext.binding;
  116. //if (!typePattern.assertExactType(world.getMessageHandler())) return;
  117. if (typePattern == TypePattern.NO) return; // already had an error here
  118. TypeX iType = typePattern.getExactType();
  119. // if (iType == null) {
  120. // throw new RuntimeException("yikes: " + typePattern);
  121. // }
  122. //if (iType == ResolvedTypeX.MISSING || iType == null) return;
  123. ReferenceBinding b = (ReferenceBinding)world.makeTypeBinding(iType); //"
  124. if (b.isClass()) {
  125. if (sourceType.isInterface()) {
  126. world.getMessageHandler().handleMessage(MessageUtil.error(
  127. "interface can not extend a class", declareParents.getSourceLocation()
  128. ));
  129. // how to handle xcutting errors???
  130. }
  131. if (sourceType == b || sourceType.isSuperclassOf(b)) {
  132. world.getMessageHandler().handleMessage(MessageUtil.error(
  133. "class can not extend itself", declareParents.getSourceLocation()
  134. ));
  135. return;
  136. }
  137. sourceType.superclass = b;
  138. } else {
  139. //??? it's not considered an error to extend yourself, nothing happens
  140. if (sourceType.equals(b)) {
  141. return;
  142. }
  143. if (sourceType.isInterface() && b.implementsInterface(sourceType, true)) {
  144. world.getMessageHandler().handleMessage(MessageUtil.error(
  145. "interface can not extend itself", declareParents.getSourceLocation()
  146. ));
  147. return;
  148. }
  149. if (sourceType == b || b.isSuperclassOf(sourceType)) return;
  150. ReferenceBinding[] oldI = sourceType.superInterfaces;
  151. ReferenceBinding[] newI;
  152. if (oldI == null) {
  153. newI = new ReferenceBinding[1];
  154. newI[0] = b;
  155. } else {
  156. int n = oldI.length;
  157. newI = new ReferenceBinding[n+1];
  158. System.arraycopy(oldI, 0, newI, 0, n);
  159. newI[n] = b;
  160. }
  161. sourceType.superInterfaces = newI;
  162. }
  163. }
  164. private TypeReference makeReference(ExactTypePattern e) {
  165. return new SingleTypeReference(e.getType().getName().toCharArray(),
  166. AstUtil.makeLongPos(e.getStart(), e.getEnd()));
  167. }
  168. }