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.

ReferenceType.java 38KB

15 years ago
15 years ago
12 years ago
15 years ago
12 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
12 years ago
15 years ago
15 years ago
15 years ago
14 years ago
14 years ago
15 years ago
15 years ago
15 years ago
12 years ago
12 years ago
12 years ago
12 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
12 years ago
15 years ago
12 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
12 years ago
15 years ago
12 years ago
15 years ago
12 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
14 years ago
14 years ago
15 years ago
14 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
14 years ago
15 years ago
14 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
14 years ago
15 years ago
12 years ago
15 years ago
15 years ago
15 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
12 years ago
15 years ago
12 years ago
15 years ago
14 years ago
12 years ago
14 years ago
15 years ago
14 years ago
15 years ago
15 years ago
15 years ago
15 years ago
11 years ago
11 years ago
11 years ago
13 years ago
15 years ago
14 years ago
14 years ago
14 years ago
14 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
15 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Contributors
  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. * Andy Clement - June 2005 - separated out from ResolvedType
  12. * ******************************************************************/
  13. package org.aspectj.weaver;
  14. import java.lang.ref.WeakReference;
  15. import java.util.ArrayList;
  16. import java.util.Collection;
  17. import java.util.List;
  18. import java.util.Map;
  19. import org.aspectj.bridge.ISourceLocation;
  20. import org.aspectj.weaver.World.TypeMap;
  21. import org.aspectj.weaver.patterns.Declare;
  22. import org.aspectj.weaver.patterns.PerClause;
  23. /**
  24. * A reference type represents some 'real' type, not a primitive, not an array -
  25. * but a real type, for example java.util.List. Each ReferenceType has a
  26. * delegate that is the underlying artifact - either an eclipse artifact or a
  27. * bcel artifact. If the type represents a raw type (i.e. there is a generic
  28. * form) then the genericType field is set to point to the generic type. If it
  29. * is for a parameterized type then the generic type is also set to point to the
  30. * generic form.
  31. */
  32. public class ReferenceType extends ResolvedType {
  33. public static final ReferenceType[] EMPTY_ARRAY = new ReferenceType[0];
  34. /**
  35. * For generic types, this list holds references to all the derived raw and
  36. * parameterized versions. We need this so that if the generic delegate is
  37. * swapped during incremental compilation, the delegate of the derivatives
  38. * is swapped also.
  39. */
  40. private final List<WeakReference<ReferenceType>> derivativeTypes = new ArrayList<WeakReference<ReferenceType>>();
  41. /**
  42. * For parameterized types (or the raw type) - this field points to the
  43. * actual reference type from which they are derived.
  44. */
  45. ReferenceType genericType = null;
  46. ReferenceType rawType = null; // generic types have a pointer back to their
  47. // raw variant (prevents GC of the raw from
  48. // the typemap!)
  49. ReferenceTypeDelegate delegate = null;
  50. int startPos = 0;
  51. int endPos = 0;
  52. // cached values for members
  53. ResolvedMember[] parameterizedMethods = null;
  54. ResolvedMember[] parameterizedFields = null;
  55. ResolvedMember[] parameterizedPointcuts = null;
  56. WeakReference<ResolvedType[]> parameterizedInterfaces = new WeakReference<ResolvedType[]>(
  57. null);
  58. Collection<Declare> parameterizedDeclares = null;
  59. // Collection parameterizedTypeMungers = null;
  60. // During matching it can be necessary to temporary mark types as annotated.
  61. // For example
  62. // a declare @type may trigger a separate declare parents to match, and so
  63. // the annotation
  64. // is temporarily held against the referencetype, the annotation will be
  65. // properly
  66. // added to the class during weaving.
  67. private ResolvedType[] annotationTypes = null;
  68. private AnnotationAJ[] annotations = null;
  69. // Similarly these are temporary replacements and additions for the
  70. // superclass and
  71. // superinterfaces
  72. private ResolvedType newSuperclass;
  73. private ResolvedType[] newInterfaces;
  74. public ReferenceType(String signature, World world) {
  75. super(signature, world);
  76. }
  77. public ReferenceType(String signature, String signatureErasure, World world) {
  78. super(signature, signatureErasure, world);
  79. }
  80. public static ReferenceType fromTypeX(UnresolvedType tx, World world) {
  81. ReferenceType rt = new ReferenceType(tx.getErasureSignature(), world);
  82. rt.typeKind = tx.typeKind;
  83. return rt;
  84. }
  85. /**
  86. * Constructor used when creating a parameterized type.
  87. */
  88. public ReferenceType(ResolvedType theGenericType,
  89. ResolvedType[] theParameters, World aWorld) {
  90. super(makeParameterizedSignature(theGenericType, theParameters),
  91. theGenericType.signatureErasure, aWorld);
  92. ReferenceType genericReferenceType = (ReferenceType) theGenericType;
  93. this.typeParameters = theParameters;
  94. this.genericType = genericReferenceType;
  95. this.typeKind = TypeKind.PARAMETERIZED;
  96. this.delegate = genericReferenceType.getDelegate();
  97. genericReferenceType.addDependentType(this);
  98. }
  99. synchronized void addDependentType(ReferenceType dependent) {
  100. // checkDuplicates(dependent);
  101. synchronized (derivativeTypes) {
  102. this.derivativeTypes
  103. .add(new WeakReference<ReferenceType>(dependent));
  104. }
  105. }
  106. public void checkDuplicates(ReferenceType newRt) {
  107. synchronized (derivativeTypes) {
  108. List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
  109. for (WeakReference<ReferenceType> derivativeTypeReference : derivativeTypes) {
  110. ReferenceType derivativeType = derivativeTypeReference.get();
  111. if (derivativeType == null) {
  112. forRemoval.add(derivativeTypeReference);
  113. } else {
  114. if (derivativeType.getTypekind() != newRt.getTypekind()) {
  115. continue; // cannot be this one
  116. }
  117. if (equal2(newRt.getTypeParameters(),
  118. derivativeType.getTypeParameters())) {
  119. if (TypeMap.useExpendableMap) {
  120. throw new IllegalStateException();
  121. }
  122. }
  123. }
  124. }
  125. derivativeTypes.removeAll(forRemoval);
  126. }
  127. }
  128. private boolean equal2(UnresolvedType[] typeParameters,
  129. UnresolvedType[] resolvedParameters) {
  130. if (typeParameters.length != resolvedParameters.length) {
  131. return false;
  132. }
  133. int len = typeParameters.length;
  134. for (int p = 0; p < len; p++) {
  135. if (!typeParameters[p].equals(resolvedParameters[p])) {
  136. return false;
  137. }
  138. }
  139. return true;
  140. }
  141. @Override
  142. public String getSignatureForAttribute() {
  143. if (genericType == null || typeParameters == null) {
  144. return getSignature();
  145. }
  146. return makeDeclaredSignature(genericType, typeParameters);
  147. }
  148. /**
  149. * Create a reference type for a generic type
  150. */
  151. public ReferenceType(UnresolvedType genericType, World world) {
  152. super(genericType.getSignature(), world);
  153. typeKind = TypeKind.GENERIC;
  154. this.typeVariables = genericType.typeVariables;
  155. }
  156. @Override
  157. public boolean isClass() {
  158. return getDelegate().isClass();
  159. }
  160. @Override
  161. public int getCompilerVersion() {
  162. return getDelegate().getCompilerVersion();
  163. }
  164. @Override
  165. public boolean isGenericType() {
  166. return !isParameterizedType() && !isRawType()
  167. && getDelegate().isGeneric();
  168. }
  169. public String getGenericSignature() {
  170. String sig = getDelegate().getDeclaredGenericSignature();
  171. return (sig == null) ? "" : sig;
  172. }
  173. @Override
  174. public AnnotationAJ[] getAnnotations() {
  175. return getDelegate().getAnnotations();
  176. }
  177. @Override
  178. public void addAnnotation(AnnotationAJ annotationX) {
  179. if (annotations == null) {
  180. annotations = new AnnotationAJ[] { annotationX };
  181. } else {
  182. AnnotationAJ[] newAnnotations = new AnnotationAJ[annotations.length + 1];
  183. System.arraycopy(annotations, 0, newAnnotations, 1,
  184. annotations.length);
  185. newAnnotations[0] = annotationX;
  186. annotations = newAnnotations;
  187. }
  188. addAnnotationType(annotationX.getType());
  189. }
  190. public boolean hasAnnotation(UnresolvedType ofType) {
  191. boolean onDelegate = getDelegate().hasAnnotation(ofType);
  192. if (onDelegate) {
  193. return true;
  194. }
  195. if (annotationTypes != null) {
  196. for (int i = 0; i < annotationTypes.length; i++) {
  197. if (annotationTypes[i].equals(ofType)) {
  198. return true;
  199. }
  200. }
  201. }
  202. return false;
  203. }
  204. private void addAnnotationType(ResolvedType ofType) {
  205. if (annotationTypes == null) {
  206. annotationTypes = new ResolvedType[1];
  207. annotationTypes[0] = ofType;
  208. } else {
  209. ResolvedType[] newAnnotationTypes = new ResolvedType[annotationTypes.length + 1];
  210. System.arraycopy(annotationTypes, 0, newAnnotationTypes, 1,
  211. annotationTypes.length);
  212. newAnnotationTypes[0] = ofType;
  213. annotationTypes = newAnnotationTypes;
  214. }
  215. }
  216. @Override
  217. public ResolvedType[] getAnnotationTypes() {
  218. if (getDelegate() == null) {
  219. throw new BCException("Unexpected null delegate for type "
  220. + this.getName());
  221. }
  222. if (annotationTypes == null) {
  223. // there are no extras:
  224. return getDelegate().getAnnotationTypes();
  225. } else {
  226. ResolvedType[] delegateAnnotationTypes = getDelegate()
  227. .getAnnotationTypes();
  228. ResolvedType[] result = new ResolvedType[annotationTypes.length
  229. + delegateAnnotationTypes.length];
  230. System.arraycopy(delegateAnnotationTypes, 0, result, 0,
  231. delegateAnnotationTypes.length);
  232. System.arraycopy(annotationTypes, 0, result,
  233. delegateAnnotationTypes.length, annotationTypes.length);
  234. return result;
  235. }
  236. }
  237. @Override
  238. public String getNameAsIdentifier() {
  239. return getRawName().replace('.', '_');
  240. }
  241. @Override
  242. public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
  243. AnnotationAJ[] axs = getDelegate().getAnnotations();
  244. if (axs != null) {
  245. for (int i = 0; i < axs.length; i++) {
  246. if (axs[i].getTypeSignature().equals(ofType.getSignature())) {
  247. return axs[i];
  248. }
  249. }
  250. }
  251. if (annotations != null) {
  252. String searchSig = ofType.getSignature();
  253. for (int i = 0; i < annotations.length; i++) {
  254. if (annotations[i].getTypeSignature().equals(searchSig)) {
  255. return annotations[i];
  256. }
  257. }
  258. }
  259. return null;
  260. }
  261. @Override
  262. public boolean isAspect() {
  263. return getDelegate().isAspect();
  264. }
  265. @Override
  266. public boolean isAnnotationStyleAspect() {
  267. return getDelegate().isAnnotationStyleAspect();
  268. }
  269. @Override
  270. public boolean isEnum() {
  271. return getDelegate().isEnum();
  272. }
  273. @Override
  274. public boolean isAnnotation() {
  275. return getDelegate().isAnnotation();
  276. }
  277. @Override
  278. public boolean isAnonymous() {
  279. return getDelegate().isAnonymous();
  280. }
  281. @Override
  282. public boolean isNested() {
  283. return getDelegate().isNested();
  284. }
  285. public ResolvedType getOuterClass() {
  286. return getDelegate().getOuterClass();
  287. }
  288. public String getRetentionPolicy() {
  289. return getDelegate().getRetentionPolicy();
  290. }
  291. @Override
  292. public boolean isAnnotationWithRuntimeRetention() {
  293. return getDelegate().isAnnotationWithRuntimeRetention();
  294. }
  295. @Override
  296. public boolean canAnnotationTargetType() {
  297. return getDelegate().canAnnotationTargetType();
  298. }
  299. @Override
  300. public AnnotationTargetKind[] getAnnotationTargetKinds() {
  301. return getDelegate().getAnnotationTargetKinds();
  302. }
  303. // true iff the statement "this = (ThisType) other" would compile
  304. @Override
  305. public boolean isCoerceableFrom(ResolvedType o) {
  306. ResolvedType other = o.resolve(world);
  307. if (this.isAssignableFrom(other) || other.isAssignableFrom(this)) {
  308. return true;
  309. }
  310. if (this.isParameterizedType() && other.isParameterizedType()) {
  311. return isCoerceableFromParameterizedType(other);
  312. }
  313. if (this.isParameterizedType() && other.isRawType()) {
  314. return ((ReferenceType) this.getRawType()).isCoerceableFrom(other
  315. .getGenericType());
  316. }
  317. if (this.isRawType() && other.isParameterizedType()) {
  318. return this.getGenericType().isCoerceableFrom((other.getRawType()));
  319. }
  320. if (!this.isInterface() && !other.isInterface()) {
  321. return false;
  322. }
  323. if (this.isFinal() || other.isFinal()) {
  324. return false;
  325. }
  326. // ??? needs to be Methods, not just declared methods? JLS 5.5 unclear
  327. ResolvedMember[] a = getDeclaredMethods();
  328. ResolvedMember[] b = other.getDeclaredMethods(); // ??? is this cast
  329. // always safe
  330. for (int ai = 0, alen = a.length; ai < alen; ai++) {
  331. for (int bi = 0, blen = b.length; bi < blen; bi++) {
  332. if (!b[bi].isCompatibleWith(a[ai])) {
  333. return false;
  334. }
  335. }
  336. }
  337. return true;
  338. }
  339. private final boolean isCoerceableFromParameterizedType(ResolvedType other) {
  340. if (!other.isParameterizedType()) {
  341. return false;
  342. }
  343. ResolvedType myRawType = getRawType();
  344. ResolvedType theirRawType = other.getRawType();
  345. if (myRawType == theirRawType
  346. || myRawType.isCoerceableFrom(theirRawType)) {
  347. if (getTypeParameters().length == other.getTypeParameters().length) {
  348. // there's a chance it can be done
  349. ResolvedType[] myTypeParameters = getResolvedTypeParameters();
  350. ResolvedType[] theirTypeParameters = other
  351. .getResolvedTypeParameters();
  352. for (int i = 0; i < myTypeParameters.length; i++) {
  353. if (myTypeParameters[i] != theirTypeParameters[i]) {
  354. // thin ice now... but List<String> may still be
  355. // coerceable from e.g. List<T>
  356. if (myTypeParameters[i].isGenericWildcard()) {
  357. BoundedReferenceType wildcard = (BoundedReferenceType) myTypeParameters[i];
  358. if (!wildcard
  359. .canBeCoercedTo(theirTypeParameters[i])) {
  360. return false;
  361. }
  362. } else if (myTypeParameters[i]
  363. .isTypeVariableReference()) {
  364. TypeVariableReferenceType tvrt = (TypeVariableReferenceType) myTypeParameters[i];
  365. TypeVariable tv = tvrt.getTypeVariable();
  366. tv.resolve(world);
  367. if (!tv.canBeBoundTo(theirTypeParameters[i])) {
  368. return false;
  369. }
  370. } else if (theirTypeParameters[i]
  371. .isTypeVariableReference()) {
  372. TypeVariableReferenceType tvrt = (TypeVariableReferenceType) theirTypeParameters[i];
  373. TypeVariable tv = tvrt.getTypeVariable();
  374. tv.resolve(world);
  375. if (!tv.canBeBoundTo(myTypeParameters[i])) {
  376. return false;
  377. }
  378. } else if (theirTypeParameters[i].isGenericWildcard()) {
  379. BoundedReferenceType wildcard = (BoundedReferenceType) theirTypeParameters[i];
  380. if (!wildcard.canBeCoercedTo(myTypeParameters[i])) {
  381. return false;
  382. }
  383. } else {
  384. return false;
  385. }
  386. }
  387. }
  388. return true;
  389. }
  390. // } else {
  391. // // we do this walk for situations like the following:
  392. // // Base<T>, Sub<S,T> extends Base<S>
  393. // // is Sub<Y,Z> coerceable from Base<X> ???
  394. // for (Iterator i = getDirectSupertypes(); i.hasNext();) {
  395. // ReferenceType parent = (ReferenceType) i.next();
  396. // if (parent.isCoerceableFromParameterizedType(other))
  397. // return true;
  398. // }
  399. }
  400. return false;
  401. }
  402. @Override
  403. public boolean isAssignableFrom(ResolvedType other) {
  404. return isAssignableFrom(other, false);
  405. }
  406. // TODO rewrite this method - it is a terrible mess
  407. // true iff the statement "this = other" would compile.
  408. @Override
  409. public boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
  410. if (other.isPrimitiveType()) {
  411. if (!world.isInJava5Mode()) {
  412. return false;
  413. }
  414. if (ResolvedType.validBoxing.contains(this.getSignature()
  415. + other.getSignature())) {
  416. return true;
  417. }
  418. }
  419. if (this == other) {
  420. return true;
  421. }
  422. if (this.getSignature().equals("Ljava/lang/Object;")) {
  423. return true;
  424. }
  425. if (!isTypeVariableReference()
  426. && other.getSignature().equals("Ljava/lang/Object;")) {
  427. return false;
  428. }
  429. boolean thisRaw = this.isRawType();
  430. if (thisRaw && other.isParameterizedOrGenericType()) {
  431. return isAssignableFrom(other.getRawType());
  432. }
  433. boolean thisGeneric = this.isGenericType();
  434. if (thisGeneric && other.isParameterizedOrRawType()) {
  435. return isAssignableFrom(other.getGenericType());
  436. }
  437. if (this.isParameterizedType()) {
  438. // look at wildcards...
  439. if (((ReferenceType) this.getRawType()).isAssignableFrom(other)) {
  440. boolean wildcardsAllTheWay = true;
  441. ResolvedType[] myParameters = this.getResolvedTypeParameters();
  442. for (int i = 0; i < myParameters.length; i++) {
  443. if (!myParameters[i].isGenericWildcard()) {
  444. wildcardsAllTheWay = false;
  445. } else {
  446. BoundedReferenceType boundedRT = (BoundedReferenceType) myParameters[i];
  447. if (boundedRT.isExtends() || boundedRT.isSuper()) {
  448. wildcardsAllTheWay = false;
  449. }
  450. }
  451. }
  452. if (wildcardsAllTheWay && !other.isParameterizedType()) {
  453. return true;
  454. }
  455. // we have to match by parameters one at a time
  456. ResolvedType[] theirParameters = other
  457. .getResolvedTypeParameters();
  458. boolean parametersAssignable = true;
  459. if (myParameters.length == theirParameters.length) {
  460. for (int i = 0; i < myParameters.length
  461. && parametersAssignable; i++) {
  462. if (myParameters[i] == theirParameters[i]) {
  463. continue;
  464. }
  465. // dont do this: pr253109
  466. // if
  467. // (myParameters[i].isAssignableFrom(theirParameters[i],
  468. // allowMissing)) {
  469. // continue;
  470. // }
  471. ResolvedType mp = myParameters[i];
  472. ResolvedType tp = theirParameters[i];
  473. if (mp.isParameterizedType()
  474. && tp.isParameterizedType()) {
  475. if (mp.getGenericType().equals(tp.getGenericType())) {
  476. UnresolvedType[] mtps = mp.getTypeParameters();
  477. UnresolvedType[] ttps = tp.getTypeParameters();
  478. for (int ii = 0; ii < mtps.length; ii++) {
  479. if (mtps[ii].isTypeVariableReference()
  480. && ttps[ii]
  481. .isTypeVariableReference()) {
  482. TypeVariable mtv = ((TypeVariableReferenceType) mtps[ii])
  483. .getTypeVariable();
  484. boolean b = mtv
  485. .canBeBoundTo((ResolvedType) ttps[ii]);
  486. if (!b) {// TODO incomplete testing here
  487. // I think
  488. parametersAssignable = false;
  489. break;
  490. }
  491. } else {
  492. parametersAssignable = false;
  493. break;
  494. }
  495. }
  496. continue;
  497. } else {
  498. parametersAssignable = false;
  499. break;
  500. }
  501. }
  502. if (myParameters[i].isTypeVariableReference()
  503. && theirParameters[i].isTypeVariableReference()) {
  504. TypeVariable myTV = ((TypeVariableReferenceType) myParameters[i])
  505. .getTypeVariable();
  506. // TypeVariable theirTV =
  507. // ((TypeVariableReferenceType)
  508. // theirParameters[i]).getTypeVariable();
  509. boolean b = myTV.canBeBoundTo(theirParameters[i]);
  510. if (!b) {// TODO incomplete testing here I think
  511. parametersAssignable = false;
  512. break;
  513. } else {
  514. continue;
  515. }
  516. }
  517. if (!myParameters[i].isGenericWildcard()) {
  518. parametersAssignable = false;
  519. break;
  520. } else {
  521. BoundedReferenceType wildcardType = (BoundedReferenceType) myParameters[i];
  522. if (!wildcardType.alwaysMatches(theirParameters[i])) {
  523. parametersAssignable = false;
  524. break;
  525. }
  526. }
  527. }
  528. } else {
  529. parametersAssignable = false;
  530. }
  531. if (parametersAssignable) {
  532. return true;
  533. }
  534. }
  535. }
  536. // eg this=T other=Ljava/lang/Object;
  537. if (isTypeVariableReference() && !other.isTypeVariableReference()) {
  538. TypeVariable aVar = ((TypeVariableReference) this)
  539. .getTypeVariable();
  540. return aVar.resolve(world).canBeBoundTo(other);
  541. }
  542. if (other.isTypeVariableReference()) {
  543. TypeVariableReferenceType otherType = (TypeVariableReferenceType) other;
  544. if (this instanceof TypeVariableReference) {
  545. return ((TypeVariableReference) this)
  546. .getTypeVariable()
  547. .resolve(world)
  548. .canBeBoundTo(
  549. otherType.getTypeVariable().getFirstBound()
  550. .resolve(world));// pr171952
  551. // return
  552. // ((TypeVariableReference)this).getTypeVariable()==otherType
  553. // .getTypeVariable();
  554. } else {
  555. // FIXME asc should this say canBeBoundTo??
  556. return this.isAssignableFrom(otherType.getTypeVariable()
  557. .getFirstBound().resolve(world));
  558. }
  559. }
  560. if (allowMissing && other.isMissing()) {
  561. return false;
  562. }
  563. ResolvedType[] interfaces = other.getDeclaredInterfaces();
  564. for (ResolvedType intface : interfaces) {
  565. boolean b;
  566. if (thisRaw && intface.isParameterizedOrGenericType()) {
  567. b = this.isAssignableFrom(intface.getRawType(), allowMissing);
  568. } else {
  569. b = this.isAssignableFrom(intface, allowMissing);
  570. }
  571. if (b) {
  572. return true;
  573. }
  574. }
  575. ResolvedType superclass = other.getSuperclass();
  576. if (superclass != null) {
  577. boolean b;
  578. if (thisRaw && superclass.isParameterizedOrGenericType()) {
  579. b = this.isAssignableFrom(superclass.getRawType(), allowMissing);
  580. } else {
  581. b = this.isAssignableFrom(superclass, allowMissing);
  582. }
  583. if (b) {
  584. return true;
  585. }
  586. }
  587. return false;
  588. }
  589. @Override
  590. public ISourceContext getSourceContext() {
  591. return getDelegate().getSourceContext();
  592. }
  593. @Override
  594. public ISourceLocation getSourceLocation() {
  595. ISourceContext isc = getDelegate().getSourceContext();
  596. return isc.makeSourceLocation(new Position(startPos, endPos));
  597. }
  598. @Override
  599. public boolean isExposedToWeaver() {
  600. return (getDelegate() == null) || delegate.isExposedToWeaver();
  601. }
  602. @Override
  603. public WeaverStateInfo getWeaverState() {
  604. return getDelegate().getWeaverState();
  605. }
  606. @Override
  607. public ResolvedMember[] getDeclaredFields() {
  608. if (parameterizedFields != null) {
  609. return parameterizedFields;
  610. }
  611. if (isParameterizedType() || isRawType()) {
  612. ResolvedMember[] delegateFields = getDelegate().getDeclaredFields();
  613. parameterizedFields = new ResolvedMember[delegateFields.length];
  614. for (int i = 0; i < delegateFields.length; i++) {
  615. parameterizedFields[i] = delegateFields[i].parameterizedWith(
  616. getTypesForMemberParameterization(), this,
  617. isParameterizedType());
  618. }
  619. return parameterizedFields;
  620. } else {
  621. return getDelegate().getDeclaredFields();
  622. }
  623. }
  624. /**
  625. * Find out from the generic signature the true signature of any interfaces
  626. * I implement. If I am parameterized, these may then need to be
  627. * parameterized before returning.
  628. */
  629. @Override
  630. public ResolvedType[] getDeclaredInterfaces() {
  631. ResolvedType[] interfaces = parameterizedInterfaces.get();
  632. if (interfaces != null) {
  633. return interfaces;
  634. }
  635. ResolvedType[] delegateInterfaces = getDelegate()
  636. .getDeclaredInterfaces();
  637. if (isRawType()) {
  638. if (newInterfaces != null) {// debug 375777
  639. throw new IllegalStateException(
  640. "The raw type should never be accumulating new interfaces, they should be on the generic type. Type is "
  641. + this.getName());
  642. }
  643. ResolvedType[] newInterfacesFromGenericType = genericType.newInterfaces;
  644. if (newInterfacesFromGenericType != null) {
  645. ResolvedType[] extraInterfaces = new ResolvedType[delegateInterfaces.length
  646. + newInterfacesFromGenericType.length];
  647. System.arraycopy(delegateInterfaces, 0, extraInterfaces, 0,
  648. delegateInterfaces.length);
  649. System.arraycopy(newInterfacesFromGenericType, 0,
  650. extraInterfaces, delegateInterfaces.length,
  651. newInterfacesFromGenericType.length);
  652. delegateInterfaces = extraInterfaces;
  653. }
  654. } else if (newInterfaces != null) {
  655. // OPTIMIZE does this part of the method trigger often?
  656. ResolvedType[] extraInterfaces = new ResolvedType[delegateInterfaces.length
  657. + newInterfaces.length];
  658. System.arraycopy(delegateInterfaces, 0, extraInterfaces, 0,
  659. delegateInterfaces.length);
  660. System.arraycopy(newInterfaces, 0, extraInterfaces,
  661. delegateInterfaces.length, newInterfaces.length);
  662. delegateInterfaces = extraInterfaces;
  663. }
  664. if (isParameterizedType()) {
  665. // UnresolvedType[] paramTypes =
  666. // getTypesForMemberParameterization();
  667. interfaces = new ResolvedType[delegateInterfaces.length];
  668. for (int i = 0; i < delegateInterfaces.length; i++) {
  669. // We may have to sub/super set the set of parametertypes if the
  670. // implemented interface
  671. // needs more or less than this type does. (pr124803/pr125080)
  672. if (delegateInterfaces[i].isParameterizedType()) {
  673. interfaces[i] = delegateInterfaces[i].parameterize(
  674. getMemberParameterizationMap()).resolve(world);
  675. } else {
  676. interfaces[i] = delegateInterfaces[i];
  677. }
  678. }
  679. parameterizedInterfaces = new WeakReference<ResolvedType[]>(
  680. interfaces);
  681. return interfaces;
  682. } else if (isRawType()) {
  683. UnresolvedType[] paramTypes = getTypesForMemberParameterization();
  684. interfaces = new ResolvedType[delegateInterfaces.length];
  685. for (int i = 0, max = interfaces.length; i < max; i++) {
  686. interfaces[i] = delegateInterfaces[i];
  687. if (interfaces[i].isGenericType()) {
  688. // a generic supertype of a raw type is replaced by its raw
  689. // equivalent
  690. interfaces[i] = interfaces[i].getRawType().resolve(
  691. getWorld());
  692. } else if (interfaces[i].isParameterizedType()) {
  693. // a parameterized supertype collapses any type vars to
  694. // their upper bounds
  695. UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(
  696. interfaces[i], paramTypes);
  697. interfaces[i] = interfaces[i]
  698. .parameterizedWith(toUseForParameterization);
  699. }
  700. }
  701. parameterizedInterfaces = new WeakReference<ResolvedType[]>(
  702. interfaces);
  703. return interfaces;
  704. }
  705. if (getDelegate().isCacheable()) {
  706. parameterizedInterfaces = new WeakReference<ResolvedType[]>(
  707. delegateInterfaces);
  708. }
  709. return delegateInterfaces;
  710. }
  711. /**
  712. * It is possible this type has multiple type variables but the interface we
  713. * are about to parameterize only uses a subset - this method determines the
  714. * subset to use by looking at the type variable names used. For example:
  715. * <code>
  716. * class Foo<T extends String,E extends Number> implements SuperInterface<T> {}
  717. * </code> where <code>
  718. * interface SuperInterface<Z> {}
  719. * </code> In that example, a use of the 'Foo' raw type should know that it
  720. * implements the SuperInterface<String>.
  721. */
  722. private UnresolvedType[] determineThoseTypesToUse(
  723. ResolvedType parameterizedInterface, UnresolvedType[] paramTypes) {
  724. // What are the type parameters for the supertype?
  725. UnresolvedType[] tParms = parameterizedInterface.getTypeParameters();
  726. UnresolvedType[] retVal = new UnresolvedType[tParms.length];
  727. // Go through the supertypes type parameters, if any of them is a type
  728. // variable, use the
  729. // real type variable on the declaring type.
  730. // it is possibly overkill to look up the type variable - ideally the
  731. // entry in the type parameter list for the
  732. // interface should be the a ref to the type variable in the current
  733. // type ... but I'm not 100% confident right now.
  734. for (int i = 0; i < tParms.length; i++) {
  735. UnresolvedType tParm = tParms[i];
  736. if (tParm.isTypeVariableReference()) {
  737. TypeVariableReference tvrt = (TypeVariableReference) tParm;
  738. TypeVariable tv = tvrt.getTypeVariable();
  739. int rank = getRank(tv.getName());
  740. // -1 probably means it is a reference to a type variable on the
  741. // outer generic type (see pr129566)
  742. if (rank != -1) {
  743. retVal[i] = paramTypes[rank];
  744. } else {
  745. retVal[i] = tParms[i];
  746. }
  747. } else {
  748. retVal[i] = tParms[i];
  749. }
  750. }
  751. return retVal;
  752. }
  753. /**
  754. * Returns the position within the set of type variables for this type for
  755. * the specified type variable name. Returns -1 if there is no type variable
  756. * with the specified name.
  757. */
  758. private int getRank(String tvname) {
  759. TypeVariable[] thisTypesTVars = getGenericType().getTypeVariables();
  760. for (int i = 0; i < thisTypesTVars.length; i++) {
  761. TypeVariable tv = thisTypesTVars[i];
  762. if (tv.getName().equals(tvname)) {
  763. return i;
  764. }
  765. }
  766. return -1;
  767. }
  768. @Override
  769. public ResolvedMember[] getDeclaredMethods() {
  770. if (parameterizedMethods != null) {
  771. return parameterizedMethods;
  772. }
  773. if (isParameterizedType() || isRawType()) {
  774. ResolvedMember[] delegateMethods = getDelegate()
  775. .getDeclaredMethods();
  776. UnresolvedType[] parameters = getTypesForMemberParameterization();
  777. parameterizedMethods = new ResolvedMember[delegateMethods.length];
  778. for (int i = 0; i < delegateMethods.length; i++) {
  779. parameterizedMethods[i] = delegateMethods[i].parameterizedWith(
  780. parameters, this, isParameterizedType());
  781. }
  782. return parameterizedMethods;
  783. } else {
  784. return getDelegate().getDeclaredMethods();
  785. }
  786. }
  787. @Override
  788. public ResolvedMember[] getDeclaredPointcuts() {
  789. if (parameterizedPointcuts != null) {
  790. return parameterizedPointcuts;
  791. }
  792. if (isParameterizedType()) {
  793. ResolvedMember[] delegatePointcuts = getDelegate()
  794. .getDeclaredPointcuts();
  795. parameterizedPointcuts = new ResolvedMember[delegatePointcuts.length];
  796. for (int i = 0; i < delegatePointcuts.length; i++) {
  797. parameterizedPointcuts[i] = delegatePointcuts[i]
  798. .parameterizedWith(getTypesForMemberParameterization(),
  799. this, isParameterizedType());
  800. }
  801. return parameterizedPointcuts;
  802. } else {
  803. return getDelegate().getDeclaredPointcuts();
  804. }
  805. }
  806. private UnresolvedType[] getTypesForMemberParameterization() {
  807. UnresolvedType[] parameters = null;
  808. if (isParameterizedType()) {
  809. parameters = getTypeParameters();
  810. } else if (isRawType()) {
  811. // raw type, use upper bounds of type variables on generic type
  812. TypeVariable[] tvs = getGenericType().getTypeVariables();
  813. parameters = new UnresolvedType[tvs.length];
  814. for (int i = 0; i < tvs.length; i++) {
  815. parameters[i] = tvs[i].getFirstBound();
  816. }
  817. }
  818. return parameters;
  819. }
  820. @Override
  821. public TypeVariable[] getTypeVariables() {
  822. if (typeVariables == null) {
  823. typeVariables = getDelegate().getTypeVariables();
  824. for (int i = 0; i < this.typeVariables.length; i++) {
  825. typeVariables[i].resolve(world);
  826. }
  827. }
  828. return typeVariables;
  829. }
  830. @Override
  831. public PerClause getPerClause() {
  832. PerClause pclause = getDelegate().getPerClause();
  833. if (pclause != null && isParameterizedType()) { // could cache the
  834. // result here...
  835. Map<String, UnresolvedType> parameterizationMap = getAjMemberParameterizationMap();
  836. pclause = (PerClause) pclause.parameterizeWith(parameterizationMap,
  837. world);
  838. }
  839. return pclause;
  840. }
  841. @Override
  842. public Collection<Declare> getDeclares() {
  843. if (parameterizedDeclares != null) {
  844. return parameterizedDeclares;
  845. }
  846. Collection<Declare> declares = null;
  847. if (ajMembersNeedParameterization()) {
  848. Collection<Declare> genericDeclares = getDelegate().getDeclares();
  849. parameterizedDeclares = new ArrayList<Declare>();
  850. Map<String, UnresolvedType> parameterizationMap = getAjMemberParameterizationMap();
  851. for (Declare declareStatement : genericDeclares) {
  852. parameterizedDeclares.add(declareStatement.parameterizeWith(
  853. parameterizationMap, world));
  854. }
  855. declares = parameterizedDeclares;
  856. } else {
  857. declares = getDelegate().getDeclares();
  858. }
  859. for (Declare d : declares) {
  860. d.setDeclaringType(this);
  861. }
  862. return declares;
  863. }
  864. @Override
  865. public Collection<ConcreteTypeMunger> getTypeMungers() {
  866. return getDelegate().getTypeMungers();
  867. }
  868. @Override
  869. public Collection<ResolvedMember> getPrivilegedAccesses() {
  870. return getDelegate().getPrivilegedAccesses();
  871. }
  872. @Override
  873. public int getModifiers() {
  874. return getDelegate().getModifiers();
  875. }
  876. WeakReference<ResolvedType> superclassReference = new WeakReference<ResolvedType>(
  877. null);
  878. @Override
  879. public ResolvedType getSuperclass() {
  880. ResolvedType ret = null;// superclassReference.get();
  881. // if (ret != null) {
  882. // return ret;
  883. // }
  884. if (newSuperclass != null) {
  885. if (this.isParameterizedType()
  886. && newSuperclass.isParameterizedType()) {
  887. return newSuperclass.parameterize(
  888. getMemberParameterizationMap()).resolve(getWorld());
  889. }
  890. if (getDelegate().isCacheable()) {
  891. superclassReference = new WeakReference<ResolvedType>(ret);
  892. }
  893. return newSuperclass;
  894. }
  895. try {
  896. world.setTypeVariableLookupScope(this);
  897. ret = getDelegate().getSuperclass();
  898. } finally {
  899. world.setTypeVariableLookupScope(null);
  900. }
  901. if (this.isParameterizedType() && ret.isParameterizedType()) {
  902. ret = ret.parameterize(getMemberParameterizationMap()).resolve(
  903. getWorld());
  904. }
  905. if (getDelegate().isCacheable()) {
  906. superclassReference = new WeakReference<ResolvedType>(ret);
  907. }
  908. return ret;
  909. }
  910. public ReferenceTypeDelegate getDelegate() {
  911. return delegate;
  912. }
  913. public void setDelegate(ReferenceTypeDelegate delegate) {
  914. // Don't copy from BcelObjectType to EclipseSourceType - the context may
  915. // be tidied (result null'd) after previous weaving
  916. if (this.delegate != null
  917. && this.delegate.copySourceContext()
  918. && this.delegate.getSourceContext() != SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) {
  919. ((AbstractReferenceTypeDelegate) delegate)
  920. .setSourceContext(this.delegate.getSourceContext());
  921. }
  922. this.delegate = delegate;
  923. synchronized (derivativeTypes) {
  924. List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
  925. for (WeakReference<ReferenceType> derivativeRef : derivativeTypes) {
  926. ReferenceType derivative = derivativeRef.get();
  927. if (derivative != null) {
  928. derivative.setDelegate(delegate);
  929. } else {
  930. forRemoval.add(derivativeRef);
  931. }
  932. }
  933. derivativeTypes.removeAll(forRemoval);
  934. }
  935. // If we are raw, we have a generic type - we should ensure it uses the
  936. // same delegate
  937. if (isRawType() && getGenericType() != null) {
  938. ReferenceType genType = (ReferenceType) getGenericType();
  939. if (genType.getDelegate() != delegate) { // avoids circular updates
  940. genType.setDelegate(delegate);
  941. }
  942. }
  943. clearParameterizationCaches();
  944. ensureConsistent();
  945. }
  946. private void clearParameterizationCaches() {
  947. parameterizedFields = null;
  948. parameterizedInterfaces.clear();
  949. parameterizedMethods = null;
  950. parameterizedPointcuts = null;
  951. superclassReference = new WeakReference<ResolvedType>(null);
  952. }
  953. public int getEndPos() {
  954. return endPos;
  955. }
  956. public int getStartPos() {
  957. return startPos;
  958. }
  959. public void setEndPos(int endPos) {
  960. this.endPos = endPos;
  961. }
  962. public void setStartPos(int startPos) {
  963. this.startPos = startPos;
  964. }
  965. @Override
  966. public boolean doesNotExposeShadowMungers() {
  967. return getDelegate().doesNotExposeShadowMungers();
  968. }
  969. public String getDeclaredGenericSignature() {
  970. return getDelegate().getDeclaredGenericSignature();
  971. }
  972. public void setGenericType(ReferenceType rt) {
  973. genericType = rt;
  974. // Should we 'promote' this reference type from simple to raw?
  975. // makes sense if someone is specifying that it has a generic form
  976. if (typeKind == TypeKind.SIMPLE) {
  977. typeKind = TypeKind.RAW;
  978. signatureErasure = signature;
  979. if (newInterfaces != null) { // debug 375777
  980. throw new IllegalStateException(
  981. "Simple type promoted to raw, but simple type had new interfaces/superclass. Type is "
  982. + this.getName());
  983. }
  984. }
  985. if (typeKind == TypeKind.RAW) {
  986. genericType.addDependentType(this);
  987. }
  988. if (isRawType()) {
  989. genericType.rawType = this;
  990. }
  991. if (this.isRawType() && rt.isRawType()) {
  992. new RuntimeException(
  993. "PR341926 diagnostics: Incorrect setup for a generic type, raw type should not point to raw: "
  994. + this.getName()).printStackTrace();
  995. }
  996. }
  997. public void demoteToSimpleType() {
  998. genericType = null;
  999. typeKind = TypeKind.SIMPLE;
  1000. signatureErasure = null;
  1001. }
  1002. @Override
  1003. public ReferenceType getGenericType() {
  1004. if (isGenericType()) {
  1005. return this;
  1006. }
  1007. return genericType;
  1008. }
  1009. /**
  1010. * a parameterized signature starts with a "P" in place of the "L", see the
  1011. * comment on signatures in UnresolvedType.
  1012. *
  1013. * @param aGenericType
  1014. * @param someParameters
  1015. * @return
  1016. */
  1017. private static String makeParameterizedSignature(ResolvedType aGenericType,
  1018. ResolvedType[] someParameters) {
  1019. String rawSignature = aGenericType.getErasureSignature();
  1020. StringBuffer ret = new StringBuffer();
  1021. ret.append(PARAMETERIZED_TYPE_IDENTIFIER);
  1022. ret.append(rawSignature.substring(1, rawSignature.length() - 1));
  1023. ret.append("<");
  1024. for (int i = 0; i < someParameters.length; i++) {
  1025. ret.append(someParameters[i].getSignature());
  1026. }
  1027. ret.append(">;");
  1028. return ret.toString();
  1029. }
  1030. private static String makeDeclaredSignature(ResolvedType aGenericType,
  1031. UnresolvedType[] someParameters) {
  1032. StringBuffer ret = new StringBuffer();
  1033. String rawSig = aGenericType.getErasureSignature();
  1034. ret.append(rawSig.substring(0, rawSig.length() - 1));
  1035. ret.append("<");
  1036. for (int i = 0; i < someParameters.length; i++) {
  1037. if (someParameters[i] instanceof ReferenceType) {
  1038. ret.append(((ReferenceType) someParameters[i])
  1039. .getSignatureForAttribute());
  1040. } else if (someParameters[i] instanceof Primitive) {
  1041. ret.append(((Primitive) someParameters[i])
  1042. .getSignatureForAttribute());
  1043. } else {
  1044. throw new IllegalStateException(
  1045. "DebugFor325731: expected a ReferenceType or Primitive but was "
  1046. + someParameters[i] + " of type "
  1047. + someParameters[i].getClass().getName());
  1048. }
  1049. }
  1050. ret.append(">;");
  1051. return ret.toString();
  1052. }
  1053. @Override
  1054. public void ensureConsistent() {
  1055. annotations = null;
  1056. annotationTypes = null;
  1057. newSuperclass = null;
  1058. newInterfaces = null;
  1059. typeVariables = null;
  1060. parameterizedInterfaces.clear();
  1061. superclassReference = new WeakReference<ResolvedType>(null);
  1062. if (getDelegate() != null) {
  1063. delegate.ensureConsistent();
  1064. }
  1065. }
  1066. @Override
  1067. public void addParent(ResolvedType newParent) {
  1068. if (this.isRawType()) {
  1069. throw new IllegalStateException(
  1070. "The raw type should never be accumulating new interfaces, they should be on the generic type. Type is "
  1071. + this.getName());
  1072. }
  1073. if (newParent.isClass()) {
  1074. newSuperclass = newParent;
  1075. superclassReference = new WeakReference<ResolvedType>(null);
  1076. } else {
  1077. if (newInterfaces == null) {
  1078. newInterfaces = new ResolvedType[1];
  1079. newInterfaces[0] = newParent;
  1080. } else {
  1081. ResolvedType[] existing = getDelegate().getDeclaredInterfaces();
  1082. if (existing != null) {
  1083. for (int i = 0; i < existing.length; i++) {
  1084. if (existing[i].equals(newParent)) {
  1085. return; // already has this interface
  1086. }
  1087. }
  1088. }
  1089. ResolvedType[] newNewInterfaces = new ResolvedType[newInterfaces.length + 1];
  1090. System.arraycopy(newInterfaces, 0, newNewInterfaces, 1,
  1091. newInterfaces.length);
  1092. newNewInterfaces[0] = newParent;
  1093. newInterfaces = newNewInterfaces;
  1094. }
  1095. if (this.isGenericType()) {
  1096. synchronized (derivativeTypes) {
  1097. for (WeakReference<ReferenceType> derivativeTypeRef : derivativeTypes) {
  1098. ReferenceType derivativeType = derivativeTypeRef.get();
  1099. if (derivativeType != null) {
  1100. derivativeType.parameterizedInterfaces.clear();
  1101. }
  1102. }
  1103. }
  1104. }
  1105. parameterizedInterfaces.clear();
  1106. }
  1107. }
  1108. private boolean equal(UnresolvedType[] typeParameters,
  1109. ResolvedType[] resolvedParameters) {
  1110. if (typeParameters.length != resolvedParameters.length) {
  1111. return false;
  1112. }
  1113. int len = typeParameters.length;
  1114. for (int p = 0; p < len; p++) {
  1115. if (!typeParameters[p].equals(resolvedParameters[p])) {
  1116. return false;
  1117. }
  1118. }
  1119. return true;
  1120. }
  1121. /**
  1122. * Look for a derivative type with the specified type parameters. This can
  1123. * avoid creating an unnecessary new (duplicate) with the same information
  1124. * in it. This method also cleans up any reference entries that have been
  1125. * null'd by a GC.
  1126. *
  1127. * @param typeParameters
  1128. * the type parameters to use when searching for the derivative
  1129. * type.
  1130. * @return an existing derivative type or null if there isn't one
  1131. */
  1132. public ReferenceType findDerivativeType(ResolvedType[] typeParameters) {
  1133. synchronized (derivativeTypes) {
  1134. List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
  1135. for (WeakReference<ReferenceType> derivativeTypeRef : derivativeTypes) {
  1136. ReferenceType derivativeType = derivativeTypeRef.get();
  1137. if (derivativeType == null) {
  1138. forRemoval.add(derivativeTypeRef);
  1139. } else {
  1140. if (derivativeType.isRawType()) {
  1141. continue;
  1142. }
  1143. if (equal(derivativeType.typeParameters, typeParameters)) {
  1144. return derivativeType; // this escape route wont remove
  1145. // the empty refs
  1146. }
  1147. }
  1148. }
  1149. derivativeTypes.removeAll(forRemoval);
  1150. }
  1151. return null;
  1152. }
  1153. public boolean hasNewInterfaces() {
  1154. return newInterfaces != null;
  1155. }
  1156. }