| 1 | /******************************************************************************* | 
| 2 |  * Copyright (c) 2008, 2009 IBM Corporation and others. | 
| 3 |  * All rights reserved. This program and the accompanying materials | 
| 4 |  * are made available under the terms of the Eclipse Public License v1.0 | 
| 5 |  * which accompanies this distribution, and is available at | 
| 6 |  * http://www.eclipse.org/legal/epl-v10.html | 
| 7 |  * | 
| 8 |  * Contributors: | 
| 9 |  *     IBM Corporation - initial API and implementation | 
| 10 |  *******************************************************************************/ | 
| 11 | package org.eclipse.pde.api.tools.internal.builder; | 
| 12 |   | 
| 13 | import org.eclipse.core.runtime.CoreException; | 
| 14 | import org.eclipse.jdt.core.Flags; | 
| 15 | import org.eclipse.pde.api.tools.internal.model.StubApiComponent; | 
| 16 | import org.eclipse.pde.api.tools.internal.provisional.Factory; | 
| 17 | import org.eclipse.pde.api.tools.internal.provisional.IApiAccess; | 
| 18 | import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations; | 
| 19 | import org.eclipse.pde.api.tools.internal.provisional.IApiDescription; | 
| 20 | import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers; | 
| 21 | import org.eclipse.pde.api.tools.internal.provisional.builder.IReference; | 
| 22 | import org.eclipse.pde.api.tools.internal.provisional.descriptors.IComponentDescriptor; | 
| 23 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent; | 
| 24 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiMember; | 
| 25 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiMethod; | 
| 26 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiType; | 
| 27 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot; | 
| 28 | import org.eclipse.pde.api.tools.internal.search.IReferenceDescriptor; | 
| 29 | import org.eclipse.pde.api.tools.internal.search.ReferenceDescriptor; | 
| 30 | import org.eclipse.pde.api.tools.internal.search.UseReportConverter; | 
| 31 | import org.eclipse.pde.api.tools.internal.util.Signatures; | 
| 32 | import org.eclipse.pde.api.tools.internal.util.Util; | 
| 33 |   | 
| 34 | /** | 
| 35 |  * Implementation of a reference from one member to another. | 
| 36 |  *  | 
| 37 |  * @since 1.0.0 | 
| 38 |  */ | 
| 39 | public class Reference implements IReference { | 
| 40 |          | 
| 41 |         /** | 
| 42 |          * Line number where the reference occurred. | 
| 43 |          */ | 
| 44 |         private int fSourceLine = -1; | 
| 45 |          | 
| 46 |         /** | 
| 47 |          * Member where the reference occurred. | 
| 48 |          */ | 
| 49 |         private IApiMember fSourceMember; | 
| 50 |          | 
| 51 |         /** | 
| 52 |          * One of the valid {@link org.eclipse.pde.api.tools.internal.provisional.search.ReferenceModifiers} | 
| 53 |          */ | 
| 54 |         private int fKind; | 
| 55 |          | 
| 56 |         /** | 
| 57 |          * One of the valid type, method, field. | 
| 58 |          */ | 
| 59 |         private int fType; | 
| 60 |          | 
| 61 |         /** | 
| 62 |          * Name of the referenced type | 
| 63 |          */ | 
| 64 |         private String fTypeName; | 
| 65 |          | 
| 66 |         /** | 
| 67 |          * Name of the referenced member or <code>null</code> | 
| 68 |          */ | 
| 69 |         private String fMemberName; | 
| 70 |          | 
| 71 |         /** | 
| 72 |          * Signature of the referenced method or <code>null</code> | 
| 73 |          */ | 
| 74 |         private String fSignature; | 
| 75 |          | 
| 76 |         /** | 
| 77 |          * Resolved reference or <code>null</code> | 
| 78 |          */ | 
| 79 |         private IApiMember fResolved; | 
| 80 |          | 
| 81 |         /** | 
| 82 |          * Resolvable status | 
| 83 |          */ | 
| 84 |         private boolean fStatus = true; | 
| 85 |          | 
| 86 |         /* (non-Javadoc) | 
| 87 |          * @see org.eclipse.pde.api.tools.internal.provisional.model.IReference#getLineNumber() | 
| 88 |          */ | 
| 89 |         public int getLineNumber() { | 
| 90 |                 return fSourceLine; | 
| 91 |         } | 
| 92 |   | 
| 93 |         /* (non-Javadoc) | 
| 94 |          * @see org.eclipse.pde.api.tools.internal.provisional.model.IReference#getMember() | 
| 95 |          */ | 
| 96 |         public IApiMember getMember() { | 
| 97 |                 return fSourceMember; | 
| 98 |         } | 
| 99 |   | 
| 100 |         /* (non-Javadoc) | 
| 101 |          * @see org.eclipse.pde.api.tools.internal.provisional.model.IReference#getReferenceKind() | 
| 102 |          */ | 
| 103 |         public int getReferenceKind() { | 
| 104 |                 return fKind; | 
| 105 |         } | 
| 106 |   | 
| 107 |         /* (non-Javadoc) | 
| 108 |          * @see org.eclipse.pde.api.tools.internal.provisional.model.IReference#getReferenceType() | 
| 109 |          */ | 
| 110 |         public int getReferenceType() { | 
| 111 |                 return fType; | 
| 112 |         } | 
| 113 |   | 
| 114 |         /* (non-Javadoc) | 
| 115 |          * @see org.eclipse.pde.api.tools.internal.provisional.model.IReference#getReferencedMember() | 
| 116 |          */ | 
| 117 |         public IApiMember getResolvedReference() { | 
| 118 |                 return fResolved; | 
| 119 |         } | 
| 120 |   | 
| 121 |         /* (non-Javadoc) | 
| 122 |          * @see org.eclipse.pde.api.tools.internal.provisional.model.IReference#getReferencedMemberName() | 
| 123 |          */ | 
| 124 |         public String getReferencedMemberName() { | 
| 125 |                 return fMemberName; | 
| 126 |         } | 
| 127 |   | 
| 128 |         /* (non-Javadoc) | 
| 129 |          * @see org.eclipse.pde.api.tools.internal.provisional.model.IReference#getReferencedSignature() | 
| 130 |          */ | 
| 131 |         public String getReferencedSignature() { | 
| 132 |                 return fSignature; | 
| 133 |         } | 
| 134 |   | 
| 135 |         /* (non-Javadoc) | 
| 136 |          * @see org.eclipse.pde.api.tools.internal.provisional.model.IReference#getReferencedTypeName() | 
| 137 |          */ | 
| 138 |         public String getReferencedTypeName() { | 
| 139 |                 return fTypeName; | 
| 140 |         } | 
| 141 |   | 
| 142 |         /** | 
| 143 |          * Creates and returns a method reference. | 
| 144 |          *  | 
| 145 |          * @param origin where the reference occurred from | 
| 146 |          * @param typeName name of the referenced type where virtual method lookup begins | 
| 147 |          * @param methodName name of the referenced method | 
| 148 |          * @param signature signature of the referenced method | 
| 149 |          * @param kind kind of method reference | 
| 150 |          */ | 
| 151 |         public static Reference methodReference(IApiMember origin, String typeName, String methodName, String signature, int kind) { | 
| 152 |                 Reference ref = new Reference(); | 
| 153 |                 ref.fSourceMember = origin; | 
| 154 |                 ref.fTypeName = typeName; | 
| 155 |                 ref.fMemberName = methodName; | 
| 156 |                 ref.fSignature = signature; | 
| 157 |                 ref.fKind = kind; | 
| 158 |                 ref.fType = IReference.T_METHOD_REFERENCE; | 
| 159 |                 return ref; | 
| 160 |         } | 
| 161 |          | 
| 162 |         /** | 
| 163 |          * Creates and returns a field reference. | 
| 164 |          *  | 
| 165 |          * @param origin where the reference occurred from | 
| 166 |          * @param typeName name of the referenced type where field lookup begins | 
| 167 |          * @param fieldName name of the referenced field | 
| 168 |          * @param kind kind of field reference | 
| 169 |          */ | 
| 170 |         public static Reference fieldReference(IApiMember origin, String typeName, String fieldName, int kind) { | 
| 171 |                 Reference ref = new Reference(); | 
| 172 |                 ref.fSourceMember = origin; | 
| 173 |                 ref.fTypeName = typeName; | 
| 174 |                 ref.fMemberName = fieldName; | 
| 175 |                 ref.fKind = kind; | 
| 176 |                 ref.fType = IReference.T_FIELD_REFERENCE; | 
| 177 |                 return ref; | 
| 178 |         }         | 
| 179 |          | 
| 180 |         /** | 
| 181 |          * Creates and returns a type reference. | 
| 182 |          *  | 
| 183 |          * @param origin where the reference occurred from | 
| 184 |          * @param typeName name of the referenced type | 
| 185 |          * @param kind kind of reference | 
| 186 |          */ | 
| 187 |         public static Reference typeReference(IApiMember origin, String typeName, int kind) { | 
| 188 |                 Reference ref = new Reference(); | 
| 189 |                 ref.fSourceMember = origin; | 
| 190 |                 ref.fTypeName = typeName; | 
| 191 |                 ref.fKind = kind; | 
| 192 |                 ref.fType = IReference.T_TYPE_REFERENCE; | 
| 193 |                 return ref; | 
| 194 |         }         | 
| 195 |          | 
| 196 |         /** | 
| 197 |          * Creates and returns a type reference. | 
| 198 |          *  | 
| 199 |          * @param origin where the reference occurred from | 
| 200 |          * @param typeName name of the referenced type | 
| 201 |          * @param signature extra type signature information | 
| 202 |          * @param kind kind of reference | 
| 203 |          */ | 
| 204 |         public static Reference typeReference(IApiMember origin, String typeName, String signature, int kind) { | 
| 205 |                 Reference ref = typeReference(origin, typeName, kind); | 
| 206 |                 ref.fSignature = signature; | 
| 207 |                 return ref; | 
| 208 |         }         | 
| 209 |          | 
| 210 |         /** | 
| 211 |          * Sets the line number - used by the reference extractor. | 
| 212 |          *  | 
| 213 |          * @param line line number | 
| 214 |          */ | 
| 215 |         void setLineNumber(int line) { | 
| 216 |                 fSourceLine = line; | 
| 217 |         } | 
| 218 |          | 
| 219 |         /** | 
| 220 |          * Resolves this reference in the given profile. | 
| 221 |          *  | 
| 222 |          * @param engine search engine resolving the reference | 
| 223 |          * @throws CoreException | 
| 224 |          */ | 
| 225 |         public void resolve() throws CoreException { | 
| 226 |                 if (!this.fStatus) { | 
| 227 |                         return; | 
| 228 |                 } | 
| 229 |                 if (fResolved == null) { | 
| 230 |                         IApiComponent sourceComponent = getMember().getApiComponent(); | 
| 231 |                         if(sourceComponent != null) { | 
| 232 |                                 IApiTypeRoot result = Util.getClassFile( | 
| 233 |                                                 sourceComponent.getBaseline().resolvePackage(sourceComponent, Signatures.getPackageName(getReferencedTypeName())), | 
| 234 |                                                 getReferencedTypeName()); | 
| 235 |                                 if(result != null) { | 
| 236 |                                         IApiType type = result.getStructure(); | 
| 237 |                                         if(type == null) { | 
| 238 |                                                 //cannot resolve a type that is in a bad classfile | 
| 239 |                                                 return; | 
| 240 |                                         } | 
| 241 |                                         switch (getReferenceType()) { | 
| 242 |                                         case IReference.T_TYPE_REFERENCE: | 
| 243 |                                                 fResolved = type; | 
| 244 |                                                 break; | 
| 245 |                                         case IReference.T_FIELD_REFERENCE: | 
| 246 |                                                 fResolved = type.getField(getReferencedMemberName()); | 
| 247 |                                                 break; | 
| 248 |                                         case IReference.T_METHOD_REFERENCE: | 
| 249 |                                                 resolveVirtualMethod(type, getReferencedMemberName(), getReferencedSignature()); | 
| 250 |                                                 break; | 
| 251 |                                         } | 
| 252 |                                 } | 
| 253 |                         } | 
| 254 |                 } | 
| 255 |                 // TODO: throw exception on failure | 
| 256 |         } | 
| 257 |         public boolean resolve(int eeValue) throws CoreException { | 
| 258 |                 IApiComponent sourceComponent = StubApiComponent.getStubApiComponent(eeValue); | 
| 259 |                 if (sourceComponent == null) { | 
| 260 |                         // if there is no source component for the ee value, the reference is considered as resolved | 
| 261 |                         return true; | 
| 262 |                 } | 
| 263 |                 IApiTypeRoot result = Util.getClassFile( | 
| 264 |                                 new IApiComponent[] { sourceComponent }, | 
| 265 |                                 getReferencedTypeName()); | 
| 266 |                 if(result != null) { | 
| 267 |                         IApiType type = result.getStructure(); | 
| 268 |                         if(type == null) { | 
| 269 |                                 return false; | 
| 270 |                         } | 
| 271 |                         switch (getReferenceType()) { | 
| 272 |                         case IReference.T_TYPE_REFERENCE: | 
| 273 |                                 return true; | 
| 274 |                         case IReference.T_FIELD_REFERENCE: | 
| 275 |                                 return type.getField(getReferencedMemberName()) != null; | 
| 276 |                         case IReference.T_METHOD_REFERENCE: | 
| 277 |                                 return resolveVirtualMethod0(sourceComponent, type, getReferencedMemberName(), getReferencedSignature()); | 
| 278 |                         } | 
| 279 |                 } | 
| 280 |                 return false; | 
| 281 |         }         | 
| 282 |         /** | 
| 283 |          * Resolves a virtual method and returns whether the method lookup was successful. | 
| 284 |          * We need to resolve the actual type that implements the method - i.e. do the virtual | 
| 285 |          * method lookup. | 
| 286 |          *  | 
| 287 |          * @param callSiteComponent the component where the method call site was located | 
| 288 |          * @param typeName referenced type name | 
| 289 |          * @param methodName referenced method name | 
| 290 |          * @param methodSignature referenced method signature | 
| 291 |          * @returns whether the lookup succeeded | 
| 292 |          * @throws CoreException if something goes terribly wrong | 
| 293 |          */ | 
| 294 |         private boolean resolveVirtualMethod(IApiType type, String methodName, String methodSignature) throws CoreException { | 
| 295 |                 IApiMethod target = type.getMethod(methodName, methodSignature); | 
| 296 |                 if (target != null) { | 
| 297 |                         if (target.isSynthetic()) { | 
| 298 |                                 // don't resolve references to synthetic methods | 
| 299 |                                 return false; | 
| 300 |                         } else { | 
| 301 |                                 fResolved = target; | 
| 302 |                                 return true; | 
| 303 |                         } | 
| 304 |                 } | 
| 305 |                 if (getReferenceKind() == IReference.REF_INTERFACEMETHOD) { | 
| 306 |                         // resolve method in super interfaces rather than class | 
| 307 |                         IApiType[] interfaces = type.getSuperInterfaces(); | 
| 308 |                         if (interfaces != null) { | 
| 309 |                                 for (int i = 0; i < interfaces.length; i++) { | 
| 310 |                                         if (resolveVirtualMethod(interfaces[i], methodName, methodSignature)) { | 
| 311 |                                                 return true; | 
| 312 |                                         } | 
| 313 |                                 } | 
| 314 |                         } | 
| 315 |                 } else { | 
| 316 |                         IApiType superT = type.getSuperclass(); | 
| 317 |                         if (superT != null) { | 
| 318 |                                 return resolveVirtualMethod(superT, methodName, methodSignature); | 
| 319 |                         } | 
| 320 |                 } | 
| 321 |                 return false; | 
| 322 |         }                 | 
| 323 |   | 
| 324 |         /** | 
| 325 |          * Resolves a virtual method and returns whether the method lookup was successful. | 
| 326 |          * We need to resolve the actual type that implements the method - i.e. do the virtual | 
| 327 |          * method lookup. | 
| 328 |          *  | 
| 329 |          * @param callSiteComponent the component where the method call site was located | 
| 330 |          * @param typeName referenced type name | 
| 331 |          * @param methodName referenced method name | 
| 332 |          * @param methodSignature referenced method signature | 
| 333 |          * @returns whether the lookup succeeded | 
| 334 |          * @throws CoreException if something goes terribly wrong | 
| 335 |          */ | 
| 336 |         private boolean resolveVirtualMethod0(IApiComponent sourceComponent, IApiType type, String methodName, String methodSignature) throws CoreException { | 
| 337 |                 IApiMethod target = type.getMethod(methodName, methodSignature); | 
| 338 |                 if (target != null) { | 
| 339 |                         if (target.isSynthetic()) { | 
| 340 |                                 // don't resolve references to synthetic methods | 
| 341 |                                 return false; | 
| 342 |                         } else { | 
| 343 |                                 return true; | 
| 344 |                         } | 
| 345 |                 } | 
| 346 |                 switch(this.fKind) { | 
| 347 |                         case IReference.REF_INTERFACEMETHOD :  | 
| 348 |                                 // resolve method in super interfaces rather than class | 
| 349 |                                 String[] interfacesNames = type.getSuperInterfaceNames(); | 
| 350 |                                 if (interfacesNames != null) { | 
| 351 |                                         for (int i = 0, max = interfacesNames.length; i < max; i++) { | 
| 352 |                                                 IApiTypeRoot classFile = Util.getClassFile( | 
| 353 |                                                                 new IApiComponent[] { sourceComponent }, | 
| 354 |                                                                 interfacesNames[i]); | 
| 355 |                                                 IApiType superinterface = classFile.getStructure(); | 
| 356 |                                                 if (superinterface != null && resolveVirtualMethod0(sourceComponent, superinterface, methodName, methodSignature)) { | 
| 357 |                                                         return true; | 
| 358 |                                                 } | 
| 359 |                                         } | 
| 360 |                                 } | 
| 361 |                                 break; | 
| 362 |                         case IReference.REF_VIRTUALMETHOD : | 
| 363 |                         case IReference.REF_SPECIALMETHOD : | 
| 364 |                                 String superclassName = type.getSuperclassName(); | 
| 365 |                                 if (superclassName != null) { | 
| 366 |                                         IApiTypeRoot classFile = Util.getClassFile( | 
| 367 |                                                         new IApiComponent[] { sourceComponent }, | 
| 368 |                                                         superclassName); | 
| 369 |                                         IApiType superclass = classFile.getStructure(); | 
| 370 |                                         boolean resolved = resolveVirtualMethod0(sourceComponent, superclass, methodName, methodSignature); | 
| 371 |                                         if (resolved) { | 
| 372 |                                                 return resolved; | 
| 373 |                                         } | 
| 374 |                                 } | 
| 375 |                                 if (Flags.isAbstract(type.getModifiers())) { | 
| 376 |                                         interfacesNames = type.getSuperInterfaceNames(); | 
| 377 |                                         if (interfacesNames != null) { | 
| 378 |                                                 for (int i = 0, max = interfacesNames.length; i < max; i++) { | 
| 379 |                                                         IApiTypeRoot classFile = Util.getClassFile( | 
| 380 |                                                                         new IApiComponent[] { sourceComponent }, | 
| 381 |                                                                         interfacesNames[i]); | 
| 382 |                                                         IApiType superinterface = classFile.getStructure(); | 
| 383 |                                                         if (superinterface != null && resolveVirtualMethod0(sourceComponent, superinterface, methodName, methodSignature)) { | 
| 384 |                                                                 return true; | 
| 385 |                                                         } | 
| 386 |                                                 } | 
| 387 |                                         } | 
| 388 |                                 } | 
| 389 |                 } | 
| 390 |                 return false; | 
| 391 |         } | 
| 392 |         /** | 
| 393 |          * Used by the search engine when resolving multiple references. | 
| 394 |          *  | 
| 395 |          * @param resolution resolved reference | 
| 396 |          */ | 
| 397 |         public void setResolution(IApiMember resolution) { | 
| 398 |                 fResolved = resolution; | 
| 399 |         } | 
| 400 |          | 
| 401 |         /* (non-Javadoc) | 
| 402 |          * @see java.lang.Object#toString() | 
| 403 |          */ | 
| 404 |         public String toString() { | 
| 405 |                 StringBuffer buf = new StringBuffer(); | 
| 406 |                 buf.append("From: "); //$NON-NLS-1$ | 
| 407 |                 IApiMember member = getMember(); | 
| 408 |                 buf.append(member.getHandle().toString()); | 
| 409 |                 if (getResolvedReference() == null) { | 
| 410 |                         buf.append("\nUnresolved To: "); //$NON-NLS-1$ | 
| 411 |                         buf.append(getReferencedTypeName()); | 
| 412 |                         if (getReferencedMemberName() != null) { | 
| 413 |                                 buf.append('#'); | 
| 414 |                                 buf.append(getReferencedMemberName()); | 
| 415 |                         } | 
| 416 |                         if (getReferencedSignature() != null) { | 
| 417 |                                 buf.append('#'); | 
| 418 |                                 buf.append(getReferencedSignature()); | 
| 419 |                         } | 
| 420 |                 } else { | 
| 421 |                         buf.append("\nResolved To: "); //$NON-NLS-1$ | 
| 422 |                         buf.append(getResolvedReference().getHandle().toString()); | 
| 423 |                 } | 
| 424 |                 buf.append("\nKind: "); //$NON-NLS-1$ | 
| 425 |                 buf.append(Reference.getReferenceText(getReferenceKind())); | 
| 426 |                 return buf.toString(); | 
| 427 |         } | 
| 428 |          | 
| 429 |         public void setResolveStatus(boolean value) { | 
| 430 |                 this.fStatus = value; | 
| 431 |         } | 
| 432 |   | 
| 433 |         /** | 
| 434 |          * Returns the string representation for the given reference kind or  | 
| 435 |          * <code>UKNOWN_KIND</code> if the kind cannot be determined. | 
| 436 |          *  | 
| 437 |          * @param kind the kid(s) to get the display text for | 
| 438 |          * @return the string for the reference kind | 
| 439 |          * @since 1.0.1 | 
| 440 |          */ | 
| 441 |         public static final String getReferenceText(int kind) { | 
| 442 |                 StringBuffer buffer = new StringBuffer(); | 
| 443 |                 if((kind & IReference.REF_EXTENDS) > 0) { | 
| 444 |                                 buffer.append("EXTENDS"); //$NON-NLS-1$ | 
| 445 |                 } | 
| 446 |                 if((kind & IReference.REF_IMPLEMENTS) > 0) { | 
| 447 |                         if(buffer.length() != 0) { | 
| 448 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 449 |                         } | 
| 450 |                         buffer.append("IMPLEMENTS"); //$NON-NLS-1$ | 
| 451 |                 } | 
| 452 |                 if ((kind & IReference.REF_SPECIALMETHOD) > 0) { | 
| 453 |                         if(buffer.length() != 0) { | 
| 454 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 455 |                         } | 
| 456 |                         buffer.append("INVOKED_SPECIAL"); //$NON-NLS-1$ | 
| 457 |                 } | 
| 458 |                 if((kind & IReference.REF_STATICMETHOD) > 0) { | 
| 459 |                         if(buffer.length() != 0) { | 
| 460 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 461 |                         } | 
| 462 |                         buffer.append("INVOKED_STATIC"); //$NON-NLS-1$ | 
| 463 |                 } | 
| 464 |                 if((kind & IReference.REF_PUTFIELD) > 0) { | 
| 465 |                         if(buffer.length() != 0) { | 
| 466 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 467 |                         } | 
| 468 |                         buffer.append("PUT_FIELD"); //$NON-NLS-1$ | 
| 469 |                 } | 
| 470 |                 if((kind & IReference.REF_PUTSTATIC) > 0) { | 
| 471 |                         if(buffer.length() != 0) { | 
| 472 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 473 |                         } | 
| 474 |                         buffer.append("PUT_STATIC_FIELD"); //$NON-NLS-1$ | 
| 475 |                 } | 
| 476 |                 if((kind & IReference.REF_FIELDDECL) > 0) { | 
| 477 |                         if(buffer.length() != 0) { | 
| 478 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 479 |                         } | 
| 480 |                         buffer.append("DECLARED_FIELD"); //$NON-NLS-1$ | 
| 481 |                 } | 
| 482 |                 if((kind & IReference.REF_PARAMETERIZED_TYPEDECL) > 0) { | 
| 483 |                         if(buffer.length() != 0) { | 
| 484 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 485 |                         } | 
| 486 |                         buffer.append("DECLARED_PARAMETERIZED_TYPE"); //$NON-NLS-1$ | 
| 487 |                 } | 
| 488 |                 if((kind & IReference.REF_PARAMETERIZED_FIELDDECL) > 0) { | 
| 489 |                         if(buffer.length() != 0) { | 
| 490 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 491 |                         } | 
| 492 |                         buffer.append("DECLARED_PARAMETERIZED_FIELD"); //$NON-NLS-1$ | 
| 493 |                 } | 
| 494 |                 if((kind & IReference.REF_PARAMETERIZED_METHODDECL) > 0) { | 
| 495 |                         if(buffer.length() != 0) { | 
| 496 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 497 |                         } | 
| 498 |                         buffer.append("DECLARED_PARAMETERIZED_METHOD"); //$NON-NLS-1$ | 
| 499 |                 } | 
| 500 |                 if((kind & IReference.REF_PARAMETER) > 0) { | 
| 501 |                         if(buffer.length() != 0) { | 
| 502 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 503 |                         } | 
| 504 |                         buffer.append("PARAMETER"); //$NON-NLS-1$ | 
| 505 |                 } | 
| 506 |                 if((kind & IReference.REF_LOCALVARIABLEDECL) > 0) { | 
| 507 |                         if(buffer.length() != 0) { | 
| 508 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 509 |                         } | 
| 510 |                         buffer.append("LOCAL_VAR_DECLARED"); //$NON-NLS-1$ | 
| 511 |                 } | 
| 512 |                 if((kind & IReference.REF_PARAMETERIZED_VARIABLE) > 0) { | 
| 513 |                         if(buffer.length() != 0) { | 
| 514 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 515 |                         } | 
| 516 |                         buffer.append("DECLARED_PARAMETERIZED_VARIABLE"); //$NON-NLS-1$ | 
| 517 |                 } | 
| 518 |                 if((kind & IReference.REF_THROWS) > 0) { | 
| 519 |                         if(buffer.length() != 0) { | 
| 520 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 521 |                         } | 
| 522 |                         buffer.append("THROWS"); //$NON-NLS-1$ | 
| 523 |                 } | 
| 524 |                 if((kind & IReference.REF_CHECKCAST) > 0) { | 
| 525 |                         if(buffer.length() != 0) { | 
| 526 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 527 |                         } | 
| 528 |                         buffer.append("CASTS"); //$NON-NLS-1$ | 
| 529 |                 } | 
| 530 |                 if((kind & IReference.REF_ARRAYALLOC) > 0) { | 
| 531 |                         if(buffer.length() != 0) { | 
| 532 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 533 |                         } | 
| 534 |                         buffer.append("ALLOCATES_ARRAY"); //$NON-NLS-1$ | 
| 535 |                 } | 
| 536 |                 if((kind & IReference.REF_CATCHEXCEPTION) > 0) { | 
| 537 |                         if(buffer.length() != 0) { | 
| 538 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 539 |                         } | 
| 540 |                         buffer.append("CATCHES_EXCEPTION"); //$NON-NLS-1$ | 
| 541 |                 } | 
| 542 |                 if((kind & IReference.REF_GETFIELD) > 0) { | 
| 543 |                         if(buffer.length() != 0) { | 
| 544 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 545 |                         } | 
| 546 |                         buffer.append("GETS_FIELD"); //$NON-NLS-1$ | 
| 547 |                 } | 
| 548 |                 if((kind & IReference.REF_GETSTATIC) > 0) { | 
| 549 |                         if(buffer.length() != 0) { | 
| 550 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 551 |                         } | 
| 552 |                         buffer.append("GETS_STATIC_FIELD"); //$NON-NLS-1$ | 
| 553 |                 } | 
| 554 |                 if((kind & IReference.REF_INSTANCEOF) > 0) { | 
| 555 |                         if(buffer.length() != 0) { | 
| 556 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 557 |                         } | 
| 558 |                         buffer.append("INSTANCEOF"); //$NON-NLS-1$ | 
| 559 |                 } | 
| 560 |                 if((kind & IReference.REF_INTERFACEMETHOD) > 0) { | 
| 561 |                         if(buffer.length() != 0) { | 
| 562 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 563 |                         } | 
| 564 |                         buffer.append("INTERFACE_METHOD"); //$NON-NLS-1$ | 
| 565 |                 } | 
| 566 |                 if((kind & IReference.REF_CONSTRUCTORMETHOD) > 0) { | 
| 567 |                         if(buffer.length() != 0) { | 
| 568 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 569 |                         } | 
| 570 |                         buffer.append("CONSTRUCTOR_METHOD"); //$NON-NLS-1$ | 
| 571 |                 } | 
| 572 |                 if((kind & IReference.REF_LOCALVARIABLE) > 0) { | 
| 573 |                         if(buffer.length() != 0) { | 
| 574 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 575 |                         } | 
| 576 |                         buffer.append("LOCAL_VARIABLE"); //$NON-NLS-1$ | 
| 577 |                 } | 
| 578 |                 if((kind & IReference.REF_PASSEDPARAMETER) > 0) { | 
| 579 |                         if(buffer.length() != 0) { | 
| 580 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 581 |                         } | 
| 582 |                         buffer.append("PASSED_PARAMETER"); //$NON-NLS-1$ | 
| 583 |                 } | 
| 584 |                 if((kind & IReference.REF_RETURNTYPE) > 0) { | 
| 585 |                         if(buffer.length() != 0) { | 
| 586 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 587 |                         } | 
| 588 |                         buffer.append("RETURN_TYPE"); //$NON-NLS-1$ | 
| 589 |                 } | 
| 590 |                 if((kind & IReference.REF_VIRTUALMETHOD) > 0) { | 
| 591 |                         if(buffer.length() != 0) { | 
| 592 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 593 |                         } | 
| 594 |                         buffer.append("VIRTUAL_METHOD"); //$NON-NLS-1$ | 
| 595 |                 } | 
| 596 |                 if((kind & IReference.REF_CONSTANTPOOL) > 0) { | 
| 597 |                         if(buffer.length() != 0) { | 
| 598 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 599 |                         } | 
| 600 |                         buffer.append("CONSTANT_POOL"); //$NON-NLS-1$ | 
| 601 |                 } | 
| 602 |                 if((kind & IReference.REF_INSTANTIATE) > 0) { | 
| 603 |                         if(buffer.length() != 0) { | 
| 604 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 605 |                         } | 
| 606 |                         buffer.append("INSTANTIATION"); //$NON-NLS-1$ | 
| 607 |                 } | 
| 608 |                 if((kind & IReference.REF_OVERRIDE) > 0) { | 
| 609 |                         if(buffer.length() != 0) { | 
| 610 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 611 |                         } | 
| 612 |                         buffer.append("OVERRIDE"); //$NON-NLS-1$ | 
| 613 |                 } | 
| 614 |                 if((kind & IReference.REF_SUPER_CONSTRUCTORMETHOD) > 0) { | 
| 615 |                         if(buffer.length() != 0) { | 
| 616 |                                 buffer.append(" | "); //$NON-NLS-1$ | 
| 617 |                         } | 
| 618 |                         buffer.append("SUPER_CONSTRUCTORMETHOD"); //$NON-NLS-1$ | 
| 619 |                 } | 
| 620 |                 if(buffer.length() == 0) { | 
| 621 |                         buffer.append(Util.UNKNOWN_KIND); | 
| 622 |                 } | 
| 623 |                 return buffer.toString(); | 
| 624 |         } | 
| 625 |          | 
| 626 |         /** | 
| 627 |          * Builds a reference descriptor from this reference or <code>null</code>. | 
| 628 |          *  | 
| 629 |          * @return corresponding reference descriptor or <code>null</code> if unresolved | 
| 630 |          * @throws CoreException if unable to resolve visibility | 
| 631 |          */ | 
| 632 |         public IReferenceDescriptor getReferenceDescriptor() throws CoreException { | 
| 633 |                 IApiMember res = getResolvedReference(); | 
| 634 |                 if (res == null) { | 
| 635 |                         return null; | 
| 636 |                 } | 
| 637 |                 IApiComponent rcomponent = res.getApiComponent(); | 
| 638 |                 IApiDescription description = rcomponent.getApiDescription(); | 
| 639 |                 IApiAnnotations annot = description.resolveAnnotations(getResolvedReference().getHandle()); | 
| 640 |                 int visibility = -1; | 
| 641 |                 IApiComponent mcomponent = getMember().getApiComponent(); | 
| 642 |                 if(annot != null) { | 
| 643 |                         visibility = annot.getVisibility(); | 
| 644 |                         if(annot.getVisibility() == VisibilityModifiers.PRIVATE) { | 
| 645 |                                 IApiComponent host = mcomponent.getHost(); | 
| 646 |                                 if(host != null && host.getId().equals(rcomponent.getId())) { | 
| 647 |                                         visibility = UseReportConverter.FRAGMENT_PERMISSIBLE; | 
| 648 |                                 } | 
| 649 |                                 else { | 
| 650 |                                         IApiAccess access = description.resolveAccessLevel( | 
| 651 |                                                         Factory.componentDescriptor(mcomponent.getId()),  // component descriptors in API description are not version qualified | 
| 652 |                                                         getResolvedReference().getHandle().getPackage()); | 
| 653 |                                         if(access != null && access.getAccessLevel() == IApiAccess.FRIEND) { | 
| 654 |                                                 visibility = VisibilityModifiers.PRIVATE_PERMISSIBLE; | 
| 655 |                                         } | 
| 656 |                                 } | 
| 657 |                         } | 
| 658 |                 } | 
| 659 |                 else { | 
| 660 |                         //overflow for those references that cannot be resolved | 
| 661 |                         visibility = VisibilityModifiers.ALL_VISIBILITIES; | 
| 662 |                 } | 
| 663 |                 return new ReferenceDescriptor( | 
| 664 |                                 (IComponentDescriptor)mcomponent.getHandle(), | 
| 665 |                                 getMember().getHandle(), | 
| 666 |                                 getLineNumber(), | 
| 667 |                                 (IComponentDescriptor)rcomponent.getHandle(), | 
| 668 |                                 res.getHandle(), | 
| 669 |                                 getReferenceKind(), visibility); | 
| 670 |         } | 
| 671 | } |