/** * Returns the signature to display for found problems * * @param member the member to get the signature from * @param qualified if the returned signature should be type-qualified or not * @return * @throws CoreException */ private String getDisplay(IApiMember member, boolean qualified) throws CoreException { String typeName = qualified ? getTypeName(member) : getSimpleTypeName(member); if (typeName.indexOf('$') != -1) { typeName = typeName.replace('$', '.'); } switch (member.getType()) { case IApiElement.FIELD: { StringBuffer buffer = new StringBuffer(); IApiField field = (IApiField) member; buffer.append(typeName).append('.').append(field.getName()); return String.valueOf(buffer); } case IApiElement.METHOD: { // reference in a method declaration IApiMethod method = (IApiMethod) member; if (qualified) { return Signatures.getMethodSignature(method); } return Signatures.getQualifiedMethodSignature(method); } default: break; } return typeName; }
/* (non-Javadoc) * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration) */ public boolean visit(MethodDeclaration node) { if (name.equals(node.getName().getFullyQualifiedName())) { if (signature.equals(Signatures.getMethodSignatureFromNode(node))) { updateTag(node); } } return false; }
/* (non-Javadoc) * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Javadoc) */ public boolean visit(Javadoc node) { List tags = node.tags(); ASTNode parent = node.getParent(); if (parent != null) { switch (parent.getNodeType()) { case ASTNode.TYPE_DECLARATION: { TypeDeclaration type = (TypeDeclaration) parent; if (type.isInterface()) { processTags( fType, pruneTags(tags, type), IApiJavadocTag.TYPE_INTERFACE, IApiJavadocTag.MEMBER_NONE); } else { processTags( fType, pruneTags(tags, type), IApiJavadocTag.TYPE_CLASS, IApiJavadocTag.MEMBER_NONE); } break; } case ASTNode.METHOD_DECLARATION: { MethodDeclaration method = (MethodDeclaration) parent; String signature = Signatures.getMethodSignatureFromNode(method); if (signature != null) { String methodname = method.getName().getFullyQualifiedName(); int member = IApiJavadocTag.MEMBER_METHOD; if (method.isConstructor()) { member = IApiJavadocTag.MEMBER_CONSTRUCTOR; methodname = "<init>"; // $NON-NLS-1$ } IMethodDescriptor descriptor = fType.getMethod(methodname, signature); processTags(descriptor, pruneTags(tags, method), getEnclosingType(method), member); } break; } case ASTNode.FIELD_DECLARATION: { FieldDeclaration field = (FieldDeclaration) parent; List fields = field.fragments(); VariableDeclarationFragment fragment = null; for (Iterator iter = fields.iterator(); iter.hasNext(); ) { fragment = (VariableDeclarationFragment) iter.next(); processTags( fType.getField(fragment.getName().getFullyQualifiedName()), pruneTags(tags, field), getEnclosingType(field), IApiJavadocTag.MEMBER_FIELD); } break; } } } return false; }
/** * 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; }
/** * 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()); } }
/** * 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.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; }
/** * 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# * 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; } }