Example #1
0
 /**
  * Tries to find the given {@link IApiMethod} in the given {@link IType}. If a matching method is
  * not found <code>null</code> is returned
  *
  * @param type the type top look in for the given {@link IApiMethod}
  * @param method the {@link IApiMethod} to look for
  * @return the {@link IMethod} from the given {@link IType} that matches the given {@link
  *     IApiMethod} or <code>null</code> if no matching method is found
  * @throws JavaModelException
  * @throws CoreException
  */
 protected IMethod findMethodInType(IType type, IApiMethod method)
     throws JavaModelException, CoreException {
   String[] parameterTypes = Signature.getParameterTypes(method.getSignature());
   for (int i = 0; i < parameterTypes.length; i++) {
     parameterTypes[i] = parameterTypes[i].replace('/', '.');
   }
   String methodname = method.getName();
   if (method.isConstructor()) {
     IApiType enclosingType = method.getEnclosingType();
     if (enclosingType.isMemberType() && !Flags.isStatic(enclosingType.getModifiers())) {
       // remove the synthetic argument that corresponds to the enclosing type
       int length = parameterTypes.length - 1;
       System.arraycopy(parameterTypes, 1, (parameterTypes = new String[length]), 0, length);
     }
     methodname = enclosingType.getSimpleName();
   }
   IMethod Qmethod = type.getMethod(methodname, parameterTypes);
   IMethod[] methods = type.getMethods();
   IMethod match = null;
   for (int i = 0; i < methods.length; i++) {
     IMethod m = methods[i];
     if (m.isSimilar(Qmethod)) {
       match = m;
       break;
     }
   }
   return match;
 }
 /**
  * Returns whether the given type has API visibility.
  *
  * @param type type
  * @return whether the given type has API visibility
  */
 private boolean isAPIType(IApiType type) throws CoreException {
   IApiDescription description = type.getApiComponent().getApiDescription();
   IApiAnnotations annotations = description.resolveAnnotations(type.getHandle());
   if (annotations == null) {
     // top level non-public top can have no annotations - they are not
     // API
     return false;
   }
   return VisibilityModifiers.isAPI(annotations.getVisibility());
 }
 /**
  * Adds all visible methods to the given set in the specified type.
  *
  * @param type type to analyze
  * @param members set to add methods to
  * @param modifiers visibilities to consider
  */
 private void gatherVisibleMethods(IApiType type, Set<MethodKey> members, int modifiers) {
   IApiMethod[] methods = type.getMethods();
   for (int i = 0; i < methods.length; i++) {
     IApiMethod method = methods[i];
     if ((method.getModifiers() & modifiers) > 0
         && !method.isConstructor()
         && !method.isSynthetic()) {
       members.add(new MethodKey(type.getName(), method.getName(), method.getSignature(), false));
     }
   }
 }
Example #4
0
 /**
  * Returns whether all enclosing types of the given member are visible.
  *
  * @param member member
  * @return whether all enclosing types of the given member are visible
  * @throws CoreException
  */
 protected boolean isEnclosingTypeVisible(IApiMember member) throws CoreException {
   IApiType type = null;
   if (member.getType() == IApiElement.TYPE) {
     type = (IApiType) member;
   } else {
     type = member.getEnclosingType();
   }
   while (type != null) {
     if (((Flags.AccPublic | Flags.AccProtected) & type.getModifiers()) == 0) {
       // the type is private or default protection, do not retain the reference
       return false;
     }
     type = type.getEnclosingType();
   }
   return true;
 }
 /**
  * Adds all API super types of the given type to the given list in top down order.
  *
  * @param superTypes list to add to
  * @param type type being processed
  */
 private void gatherAPISuperTypes(List<IApiType> superTypes, IApiType type) throws CoreException {
   if (type != null) {
     if (isAPIType(type)) {
       superTypes.add(0, type);
     }
     gatherAPISuperTypes(superTypes, type.getSuperclass());
     IApiType[] interfaces = type.getSuperInterfaces();
     if (interfaces != null) {
       for (int i = 0; i < interfaces.length; i++) {
         if (isAPIType(interfaces[i])) {
           superTypes.add(interfaces[i]);
           gatherAPISuperTypes(superTypes, interfaces[i]);
         }
       }
     }
   }
 }
Example #6
0
 /**
  * Returns the fully qualified type name associated with the given member.
  *
  * @param member
  * @return fully qualified type name
  */
 protected String getTypeName(IApiMember member) throws CoreException {
   switch (member.getType()) {
     case IApiElement.TYPE:
       {
         IApiType type = (IApiType) member;
         if (type.isAnonymous()) {
           return getTypeName(member.getEnclosingType());
         } else if (type.isLocal()) {
           return getTypeName(member.getEnclosingType());
         }
         return member.getName();
       }
     default:
       {
         return getTypeName(member.getEnclosingType());
       }
   }
 }
 /**
  * Returns whether the given type has any visible fields base on the given visibility flags to
  * consider. A field is visible signals a definite leak.
  *
  * @param type type to analyze
  * @param modifiers visibilities to consider
  * @return whether there are any visible fields
  */
 private boolean hasVisibleField(IApiType type, int modifiers) {
   IApiField[] fields = type.getFields();
   for (int i = 0; i < fields.length; i++) {
     IApiField field = fields[i];
     if ((field.getModifiers() & modifiers) > 0) {
       return true;
     }
   }
   return false;
 }
Example #8
0
 /**
  * Returns whether the referenced type name matches a non-API package.
  *
  * @param reference
  * @return whether the referenced type name matches a non-API package
  */
 protected boolean isNonAPIReference(IReference reference) {
   String packageName = Signatures.getPackageName(reference.getReferencedTypeName());
   if (fNonApiPackageNames.contains(packageName)) {
     return true;
   }
   // could be a reference to a package visible type
   IApiMember member = reference.getMember();
   IApiType type = null;
   if (member.getType() == IApiElement.TYPE) {
     type = (IApiType) member;
   } else {
     type = (IApiType) member.getAncestor(IApiElement.TYPE);
   }
   String origin = Signatures.getPackageName(type.getName());
   if (packageName.equals(origin)) {
     return true; // possible package visible reference
   }
   return false;
 }
Example #9
0
 /**
  * Returns the unqualified type name associated with the given member.
  *
  * @param member
  * @return unqualified type name
  */
 protected String getSimpleTypeName(IApiMember member) throws CoreException {
   switch (member.getType()) {
     case IApiElement.TYPE:
       {
         IApiType type = (IApiType) member;
         if (type.isAnonymous()) {
           return getSimpleTypeName(type.getEnclosingType());
         } else if (type.isLocal()) {
           String name = getSimpleTypeName(member.getEnclosingType());
           int idx = name.indexOf('$');
           if (idx > -1) {
             return name.substring(0, idx);
           }
           return name;
         }
         return Signatures.getTypeName(Signatures.getTypeSignature(type));
       }
     default:
       return getSimpleTypeName(member.getEnclosingType());
   }
 }
Example #10
0
 /**
  * Returns a method descriptor with a resolved signature for the given method descriptor with an
  * unresolved signature.
  *
  * @param descriptor method to resolve
  * @return resolved method descriptor or the same method descriptor if unable to resolve
  * @exception CoreException if unable to resolve the method and a class file container was
  *     provided for this purpose
  */
 private IMethodDescriptor resolveMethod(IMethodDescriptor descriptor) throws CoreException {
   if (fContainer != null) {
     IReferenceTypeDescriptor type = descriptor.getEnclosingType();
     IApiTypeRoot classFile = fContainer.findTypeRoot(type.getQualifiedName());
     if (classFile != null) {
       IApiType structure = classFile.getStructure();
       if (structure != null) {
         IApiMethod[] methods = structure.getMethods();
         for (int i = 0; i < methods.length; i++) {
           IApiMethod method = methods[i];
           if (descriptor.getName().equals(method.getName())) {
             String signature = method.getSignature();
             String descriptorSignature = descriptor.getSignature().replace('/', '.');
             if (Signatures.matchesSignatures(
                 descriptorSignature, signature.replace('/', '.'))) {
               return descriptor.getEnclosingType().getMethod(method.getName(), signature);
             }
             String genericSignature = method.getGenericSignature();
             if (genericSignature != null) {
               if (Signatures.matchesSignatures(
                   descriptorSignature, genericSignature.replace('/', '.'))) {
                 return descriptor.getEnclosingType().getMethod(method.getName(), signature);
               }
             }
           }
         }
       }
     }
     throw new CoreException(
         new Status(
             IStatus.ERROR,
             ApiPlugin.PLUGIN_ID,
             MessageFormat.format(
                 "Unable to resolve method signature: {0}",
                 new String[] {descriptor.toString()}),
             null)); //$NON-NLS-1$
   }
   return descriptor;
 }
 /*
  * (non-Javadoc)
  * @see
  * org.eclipse.pde.api.tools.internal.search.AbstractTypeLeakDetector#isProblem
  * (org.eclipse.pde.api.tools.internal.provisional.model.IReference)
  */
 @Override
 public boolean isProblem(IReference reference) {
   if (super.isProblem(reference)) {
     // check the use restrictions on the API type (can be extended or
     // not)
     IApiType type = (IApiType) reference.getMember();
     IApiComponent component = type.getApiComponent();
     try {
       if (type.isClass()) {
         int modifiers = 0;
         IApiAnnotations annotations =
             component.getApiDescription().resolveAnnotations(type.getHandle());
         if (annotations != null) {
           // if annotations are null, the reference should not
           // have been retained
           // as it indicates a reference from a top level non
           // public type
           if (RestrictionModifiers.isExtendRestriction(annotations.getRestrictions())) {
             // The no extend restriction means only public
             // members can be seen
             modifiers = Flags.AccPublic;
           } else {
             if (Flags.isFinal(type.getModifiers())) {
               // if final then only public members can be seen
               modifiers = Flags.AccPublic;
             } else {
               // public and protected members can be seen
               modifiers = Flags.AccPublic | Flags.AccProtected;
             }
           }
           IApiType nonApiSuper = type.getSuperclass();
           // collect all visible methods in non-API types
           Set<MethodKey> methods = new HashSet<MethodKey>();
           while (!isAPIType(nonApiSuper)) {
             if (hasVisibleField(nonApiSuper, modifiers)) {
               // a visible field in a non-API type is a
               // definite leak
               return true;
             }
             gatherVisibleMethods(nonApiSuper, methods, modifiers);
             nonApiSuper = nonApiSuper.getSuperclass();
           }
           if (methods.size() > 0) {
             // check if the visible members are part of an API
             // interface/class
             List<IApiType> apiTypes = new LinkedList<IApiType>();
             apiTypes.add(type);
             gatherAPISuperTypes(apiTypes, type);
             for (IApiType t2 : apiTypes) {
               Set<MethodKey> apiMembers = new HashSet<MethodKey>();
               gatherVisibleMethods(t2, apiMembers, modifiers);
               methods.removeAll(apiMembers);
               if (methods.size() == 0) {
                 // there are no visible methods left that
                 // are not part of an API type/interface
                 return false;
               }
             }
             if (methods.size() > 0) {
               // there are visible members that are not part
               // of an API type/interface
               return true;
             }
           }
         }
       } else {
         // don't process interfaces, enums, annotations
         return true;
       }
     } catch (CoreException ce) {
       if (ApiPlugin.DEBUG_PROBLEM_DETECTOR) {
         ApiPlugin.log(ce);
       }
       return true;
     }
   }
   return false;
 }