/*
  * (non-Javadoc)
  * @see
  * org.eclipse.pde.api.tools.internal.provisional.search.IApiProblemDetector
  * #createProblems()
  */
 @Override
 public List<IApiProblem> createProblems() {
   List<IReference> references = getRetainedReferences();
   List<IApiProblem> problems = new LinkedList<IApiProblem>();
   for (IReference reference : references) {
     if (isProblem(reference)) {
       try {
         IApiProblem problem = null;
         IApiComponent component = reference.getMember().getApiComponent();
         if (component instanceof ProjectComponent) {
           ProjectComponent ppac = (ProjectComponent) component;
           IJavaProject project = ppac.getJavaProject();
           problem = createProblem(reference, project);
         } else {
           problem = createProblem(reference);
         }
         if (problem != null) {
           problems.add(problem);
         }
       } catch (CoreException e) {
         ApiPlugin.log(e.getStatus());
       }
     }
   }
   return problems;
 }
Example #2
0
 /* (non-Javadoc)
  * @see org.eclipse.pde.api.tools.internal.provisional.search.IApiProblemDetector#createProblems()
  */
 public List createProblems() {
   List references = getRetainedReferences();
   List problems = new LinkedList();
   Iterator iterator = references.iterator();
   while (iterator.hasNext()) {
     IReference reference = (IReference) iterator.next();
     if (reference.getResolvedReference() == null) {
       // TODO: unresolved reference
     } else {
       if (isProblem(reference)) {
         try {
           IApiProblem problem = null;
           IApiComponent component = reference.getMember().getApiComponent();
           if (component instanceof ProjectComponent) {
             ProjectComponent ppac = (ProjectComponent) component;
             IJavaProject project = ppac.getJavaProject();
             problem = createProblem(reference, project);
           } else {
             problem = createProblem(reference);
           }
           if (problem != null) {
             problems.add(problem);
           }
         } catch (CoreException e) {
           ApiPlugin.log(e.getStatus());
         }
       }
     }
   }
   return problems;
 }
 /*
  * (non-Javadoc)
  * @see
  * org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#isProblem
  * (org.eclipse.pde.api.tools.internal.provisional.model.IReference)
  */
 @Override
 protected boolean isProblem(IReference reference) {
   // the reference must be in the system library
   try {
     IApiMember member = reference.getMember();
     IApiComponent apiComponent = member.getApiComponent();
     String[] lowestEEs = apiComponent.getLowestEEs();
     if (lowestEEs == null) {
       // this should not be true for Eclipse bundle as they should
       // always have a EE set
       return false;
     }
     loop:
     for (int i = 0, max = lowestEEs.length; i < max; i++) {
       String lowestEE = lowestEEs[i];
       int eeValue = ProfileModifiers.getValue(lowestEE);
       if (eeValue == ProfileModifiers.NO_PROFILE_VALUE) {
         return false;
       }
       if (!((Reference) reference).resolve(eeValue)) {
         /*
          * Make sure that the resolved reference doesn't below to
          * one of the imported package of the current component
          */
         if (apiComponent instanceof BundleComponent) {
           BundleDescription bundle = ((BundleComponent) apiComponent).getBundleDescription();
           ImportPackageSpecification[] importPackages = bundle.getImportPackages();
           String referencedTypeName = reference.getReferencedTypeName();
           int index = referencedTypeName.lastIndexOf('.');
           String packageName = referencedTypeName.substring(0, index);
           for (int j = 0, max2 = importPackages.length; j < max2; j++) {
             ImportPackageSpecification importPackageSpecification = importPackages[j];
             // get the IPackageDescriptor for the element
             // descriptor
             String importPackageName = importPackageSpecification.getName();
             if (importPackageName.equals(packageName)) {
               continue loop;
             }
           }
         }
         if (this.referenceEEs == null) {
           this.referenceEEs = new HashMap<IReference, Integer>(3);
         }
         this.referenceEEs.put(reference, new Integer(eeValue));
         return true;
       }
     }
   } catch (CoreException e) {
     ApiPlugin.log(e);
   }
   return false;
 }
Example #4
0
 /**
  * Returns whether the resolved reference is a real problem.
  *
  * @param reference
  * @return whether a problem
  */
 protected boolean isProblem(IReference reference) {
   // by default fragment -> host references are not problems
   // https://bugs.eclipse.org/bugs/show_bug.cgi?id=255659
   IApiMember member = reference.getResolvedReference();
   if (member != null) {
     IApiMember local = reference.getMember();
     try {
       IApiComponent lcomp = local.getApiComponent();
       if (lcomp != null && lcomp.isFragment()) {
         return !lcomp.getHost().equals(member.getApiComponent());
       }
     } catch (CoreException ce) {
       ApiPlugin.log(ce);
     }
   }
   return true;
 }
Example #5
0
 /**
  * @param reference
  * @return
  * @throws CoreException
  */
 public IApiProblem createProblem(IReference reference) throws CoreException {
   int lineNumber = reference.getLineNumber();
   if (lineNumber > 0) {
     lineNumber--;
   }
   String ltypename = getTypeName(reference.getMember());
   return ApiProblemFactory.newApiUsageProblem(
       null,
       ltypename,
       getQualifiedMessageArgs(reference),
       new String[] {IApiMarkerConstants.API_MARKER_ATTR_ID},
       new Object[] {new Integer(IApiMarkerConstants.API_USAGE_MARKER_ID)},
       lineNumber,
       IApiProblem.NO_CHARRANGE,
       IApiProblem.NO_CHARRANGE,
       getElementType(reference),
       getProblemKind(),
       getProblemFlags(reference));
 }
Example #6
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;
 }
 /*
  * (non-Javadoc)
  * @see
  * org.eclipse.pde.api.tools.internal.provisional.builder.IApiProblemDetector
  * #
  * considerReference(org.eclipse.pde.api.tools.internal.provisional.builder.
  * IReference)
  */
 @Override
 public boolean considerReference(IReference reference) {
   try {
     IApiComponent apiComponent = reference.getMember().getApiComponent();
     IApiBaseline baseline = apiComponent.getBaseline();
     if (baseline == null) {
       return false;
     }
     String referencedTypeName = reference.getReferencedTypeName();
     // extract the package name
     int index = referencedTypeName.lastIndexOf('.');
     if (index == -1) {
       return false;
     }
     String substring = referencedTypeName.substring(0, index);
     IApiComponent[] resolvePackages = baseline.resolvePackage(apiComponent, substring);
     switch (resolvePackages.length) {
       case 1:
         {
           if (resolvePackages[0].isSystemComponent()) {
             switch (reference.getReferenceKind()) {
               case IReference.REF_OVERRIDE:
               case IReference.REF_CONSTANTPOOL:
                 return false;
               default:
                 break;
             }
             ((Reference) reference).setResolveStatus(false);
             retainReference(reference);
             return true;
           }
           break;
         }
       default:
         break;
     }
   } catch (CoreException e) {
     ApiPlugin.log(e);
   }
   return false;
 }
 /*
  * (non-Javadoc)
  * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#
  * getElementType
  * (org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
  */
 @Override
 protected int getElementType(IReference reference) {
   IApiMember member = reference.getMember();
   switch (member.getType()) {
     case IApiElement.TYPE:
       return IElementDescriptor.TYPE;
     case IApiElement.METHOD:
       return IElementDescriptor.METHOD;
     case IApiElement.FIELD:
       return IElementDescriptor.FIELD;
     default:
       return 0;
   }
 }
 /*
  * (non-Javadoc)
  * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#
  * getProblemFlags
  * (org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
  */
 @Override
 protected int getProblemFlags(IReference reference) {
   switch (reference.getReferenceType()) {
     case IReference.T_TYPE_REFERENCE:
       {
         return IApiProblem.NO_FLAGS;
       }
     case IReference.T_METHOD_REFERENCE:
       {
         if (Util.isConstructor(reference.getReferencedMemberName())) {
           return IApiProblem.CONSTRUCTOR_METHOD;
         }
         return IApiProblem.METHOD;
       }
     case IReference.T_FIELD_REFERENCE:
       {
         return IApiProblem.FIELD;
       }
     default:
       {
         return IApiProblem.NO_FLAGS;
       }
   }
 }
Example #10
0
 protected boolean isReferenceFromComponent(IReference reference, Object componentId) {
   if (componentId != null) {
     final IApiComponent apiComponent = reference.getResolvedReference().getApiComponent();
     // API component is either component id itself or one of its fragment
     if (apiComponent.getSymbolicName().equals(componentId)) {
       return true;
     }
     try {
       final IApiComponent host = apiComponent.getHost();
       return host != null && host.getSymbolicName().equals(componentId);
     } catch (CoreException e) {
       ApiPlugin.log(e);
     }
   }
   return false;
 }
Example #11
0
 protected Position getFieldNameRange(
     String typeName, String fieldName, IDocument document, IReference reference)
     throws BadLocationException, CoreException {
   int linenumber = reference.getLineNumber();
   if (linenumber > 0) {
     linenumber--;
   }
   if (linenumber > 0) {
     int offset = document.getLineOffset(linenumber);
     String line = document.get(offset, document.getLineLength(linenumber));
     String qname = typeName + "." + fieldName; // $NON-NLS-1$
     int first = line.indexOf(qname);
     if (first < 0) {
       qname = "super." + fieldName; // $NON-NLS-1$
       first = line.indexOf(qname);
     }
     if (first < 0) {
       qname = "this." + fieldName; // $NON-NLS-1$
       first = line.indexOf(qname);
     }
     if (first < 0) {
       // try a pattern [.*fieldname]
       // the field might be ref'd via a constant, e.g. enum constant
       int idx = line.indexOf(fieldName);
       while (idx > -1) {
         if (line.charAt(idx - 1) == '.') {
           first = idx;
           qname = fieldName;
           break;
         }
         idx = line.indexOf(fieldName, idx + 1);
       }
     }
     Position pos = null;
     if (first > -1) {
       pos = new Position(offset + first, qname.length());
     } else {
       // optimistically select the whole line since we can't find the correct variable name and we
       // can't just select
       // the first occurrence
       pos = new Position(offset, line.length());
     }
     return pos;
   }
   return null;
 }
Example #12
0
 /**
  * Searches for the name of a method at the line number specified in the given reference.
  *
  * @param name method name
  * @param document document to search in
  * @param reference provides line number
  * @return method name range
  * @throws CoreException
  */
 protected Position getMethodNameRange(
     boolean isContructor, String name, IDocument document, IReference reference)
     throws CoreException, BadLocationException {
   int linenumber = reference.getLineNumber();
   if (linenumber > 0) {
     linenumber--;
   }
   String methodname = name;
   int idx = methodname.indexOf('$');
   if (idx > -1) {
     methodname = methodname.substring(0, idx);
   }
   idx = methodname.indexOf(Signatures.getLT());
   if (idx > -1) {
     methodname = methodname.substring(0, idx);
   }
   int offset = document.getLineOffset(linenumber);
   String line = document.get(offset, document.getLineLength(linenumber));
   int start = line.indexOf('=');
   if (start < 0) {
     if (isContructor) {
       // new keyword should only be checked if the method is a constructor
       start = line.indexOf("new"); // $NON-NLS-1$
       if (start < 0) {
         start = 0;
       }
     } else {
       start = 0;
     }
   } else {
     char charat = line.charAt(start - 1);
     // make sure its not '==' | '!=' | '<=' | '>='
     if (line.charAt(start + 1) == '=' || charat == '!' || charat == '<' || charat == '>') {
       start = 0;
     }
   }
   int first = findMethodNameStart(methodname, line, start);
   if (first < 0) {
     methodname = "super"; // $NON-NLS-1$
     first = findMethodNameStart(methodname, line, start);
   }
   if (first > -1) {
     return new Position(offset + first, methodname.length());
   }
   return null;
 }
 /*
  * (non-Javadoc)
  * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#
  * getMessageArgs
  * (org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
  */
 @Override
 protected String[] getMessageArgs(IReference reference) throws CoreException {
   IApiMember member = reference.getMember();
   String eeValue = ProfileModifiers.getName(this.referenceEEs.get(reference).intValue());
   String simpleTypeName = Signatures.getSimpleTypeName(reference.getReferencedTypeName());
   if (simpleTypeName.indexOf('$') != -1) {
     simpleTypeName = simpleTypeName.replace('$', '.');
   }
   switch (reference.getReferenceType()) {
     case IReference.T_TYPE_REFERENCE:
       {
         return new String[] {
           getDisplay(member, false), simpleTypeName, eeValue,
         };
       }
     case IReference.T_FIELD_REFERENCE:
       {
         return new String[] {
           getDisplay(member, false), simpleTypeName,
           reference.getReferencedMemberName(), eeValue,
         };
       }
     case IReference.T_METHOD_REFERENCE:
       {
         String referenceMemberName = reference.getReferencedMemberName();
         if (Util.isConstructor(referenceMemberName)) {
           return new String[] {
             getDisplay(member, false),
             Signature.toString(
                 reference.getReferencedSignature(), simpleTypeName, null, false, false),
             eeValue,
           };
         } else {
           return new String[] {
             getDisplay(member, false),
             simpleTypeName,
             Signature.toString(
                 reference.getReferencedSignature(), referenceMemberName, null, false, false),
             eeValue,
           };
         }
       }
     default:
       break;
   }
   return null;
 }
 /*
  * (non-Javadoc)
  * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector#
  * getSourceRange(org.eclipse.jdt.core.IType,
  * org.eclipse.jface.text.IDocument,
  * org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
  */
 @Override
 protected Position getSourceRange(IType type, IDocument document, IReference reference)
     throws CoreException, BadLocationException {
   switch (reference.getReferenceType()) {
     case IReference.T_TYPE_REFERENCE:
       {
         int linenumber = reference.getLineNumber();
         if (linenumber > 0) {
           // line number starts at 0 for the
           linenumber--;
         }
         if (linenumber > 0) {
           int offset = document.getLineOffset(linenumber);
           String line = document.get(offset, document.getLineLength(linenumber));
           String qname = reference.getReferencedTypeName().replace('$', '.');
           int first = line.indexOf(qname);
           if (first < 0) {
             qname = Signatures.getSimpleTypeName(reference.getReferencedTypeName());
             qname = qname.replace('$', '.');
             first = line.indexOf(qname);
           }
           Position pos = null;
           if (first > -1) {
             pos = new Position(offset + first, qname.length());
           } else {
             // optimistically select the whole line since we can't
             // find the correct variable name and we can't just
             // select
             // the first occurrence
             pos = new Position(offset, line.length());
           }
           return pos;
         } else {
           IApiMember apiMember = reference.getMember();
           switch (apiMember.getType()) {
             case IApiElement.FIELD:
               {
                 IApiField field = (IApiField) reference.getMember();
                 return getSourceRangeForField(type, reference, field);
               }
             case IApiElement.METHOD:
               {
                 // reference in a method declaration
                 IApiMethod method = (IApiMethod) reference.getMember();
                 return getSourceRangeForMethod(type, reference, method);
               }
             default:
               break;
           }
           // reference in a type declaration
           ISourceRange range = type.getNameRange();
           Position pos = null;
           if (range != null) {
             pos = new Position(range.getOffset(), range.getLength());
           }
           if (pos == null) {
             return defaultSourcePosition(type, reference);
           }
           return pos;
         }
       }
     case IReference.T_FIELD_REFERENCE:
       {
         int linenumber = reference.getLineNumber();
         if (linenumber > 0) {
           return getFieldNameRange(
               reference.getReferencedTypeName(),
               reference.getReferencedMemberName(),
               document,
               reference);
         }
         // reference in a field declaration
         IApiField field = (IApiField) reference.getMember();
         return getSourceRangeForField(type, reference, field);
       }
     case IReference.T_METHOD_REFERENCE:
       {
         if (reference.getLineNumber() >= 0) {
           String referenceMemberName = reference.getReferencedMemberName();
           String methodName = null;
           boolean isConstructor = Util.isConstructor(referenceMemberName);
           if (isConstructor) {
             methodName =
                 Signatures.getSimpleTypeName(reference.getReferencedTypeName().replace('$', '.'));
           } else {
             methodName = referenceMemberName;
           }
           Position pos = getMethodNameRange(isConstructor, methodName, document, reference);
           if (pos == null) {
             return defaultSourcePosition(type, reference);
           }
           return pos;
         }
         // reference in a method declaration
         IApiMethod method = (IApiMethod) reference.getMember();
         return getSourceRangeForMethod(type, reference, method);
       }
     default:
       return null;
   }
 }
 /*
  * (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;
 }
Example #16
0
 /**
  * Creates a problem for a specific reference in the workspace
  *
  * @param reference reference
  * @param associated java project (with reference source location)
  * @return problem or <code>null</code> if none
  * @exception CoreException if something goes wrong
  */
 protected IApiProblem createProblem(IReference reference, IJavaProject javaProject) {
   IProject project = javaProject.getProject();
   if (ApiPlugin.getDefault().getSeverityLevel(getSeverityKey(), project)
       == ApiPlugin.SEVERITY_IGNORE) {
     return null;
   }
   try {
     String lookupName = getTypeName(reference.getMember()).replace('$', '.');
     IType type = javaProject.findType(lookupName, new NullProgressMonitor());
     if (type == null) {
       return null;
     }
     ICompilationUnit compilationUnit = type.getCompilationUnit();
     if (compilationUnit == null) {
       return null;
     }
     IResource resource = Util.getResource(project, type);
     if (resource == null) {
       return null;
     }
     int charStart = -1;
     int charEnd = -1;
     int lineNumber = reference.getLineNumber();
     IJavaElement element = compilationUnit;
     if (!Util.isManifest(resource.getProjectRelativePath()) && !type.isBinary()) {
       IDocument document = Util.getDocument(compilationUnit);
       // retrieve line number, char start and char end
       if (lineNumber > 0) {
         lineNumber--;
       }
       // get the source range for the problem
       try {
         Position pos = getSourceRange(type, document, reference);
         if (pos != null) {
           charStart = pos.getOffset();
           if (charStart != -1) {
             charEnd = charStart + pos.getLength();
             lineNumber = document.getLineOfOffset(charStart);
           }
         }
       } catch (CoreException e) {
         ApiPlugin.log(e);
         return null;
       } catch (BadLocationException e) {
         ApiPlugin.log(e);
         return null;
       }
       if (charStart > -1) {
         element = compilationUnit.getElementAt(charStart);
       }
     }
     return ApiProblemFactory.newApiUsageProblem(
         resource.getProjectRelativePath().toPortableString(),
         type.getFullyQualifiedName(),
         getMessageArgs(reference),
         new String[] {
           IApiMarkerConstants.MARKER_ATTR_HANDLE_ID, IApiMarkerConstants.API_MARKER_ATTR_ID
         },
         new Object[] {
           (element == null
               ? compilationUnit.getHandleIdentifier()
               : element.getHandleIdentifier()),
           new Integer(IApiMarkerConstants.API_USAGE_MARKER_ID)
         },
         lineNumber,
         charStart,
         charEnd,
         getElementType(reference),
         getProblemKind(),
         getProblemFlags(reference));
   } catch (CoreException e) {
     ApiPlugin.log(e);
   }
   return null;
 }
Example #17
0
 /* (non-Javadoc)
  * @see org.eclipse.pde.api.tools.internal.provisional.builder.IApiProblemDetector#considerReference(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
  */
 public boolean considerReference(IReference reference) {
   return reference != null && (reference.getReferenceKind() & getReferenceKinds()) > 0;
 }