Example usage for org.eclipse.jdt.internal.compiler.env IBinaryMethod getGenericSignature

List of usage examples for org.eclipse.jdt.internal.compiler.env IBinaryMethod getGenericSignature

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.env IBinaryMethod getGenericSignature.

Prototype

char[] getGenericSignature();

Source Link

Document

Answer the receiver's MethodSignature, which describes the type parameters, parameter types, return type, and exception types as specified in "4.7.9.1 Signatures" of the Java SE 8 VM spec.

Usage

From source file:com.codenvy.ide.ext.java.server.internal.core.BinaryMethod.java

License:Open Source License

public String[] getExceptionTypes() throws JavaModelException {
    if (this.exceptionTypes == null) {
        IBinaryMethod info = (IBinaryMethod) getElementInfo();
        char[] genericSignature = info.getGenericSignature();
        if (genericSignature != null) {
            char[] dotBasedSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.');
            this.exceptionTypes = Signature.getThrownExceptionTypes(new String(dotBasedSignature));
        }//from   w w w  . j a  v a 2  s  . c  o m
        if (this.exceptionTypes == null || this.exceptionTypes.length == 0) {
            char[][] eTypeNames = info.getExceptionTypeNames();
            if (eTypeNames == null || eTypeNames.length == 0) {
                this.exceptionTypes = CharOperation.NO_STRINGS;
            } else {
                eTypeNames = ClassFile.translatedNames(eTypeNames);
                this.exceptionTypes = new String[eTypeNames.length];
                for (int j = 0, length = eTypeNames.length; j < length; j++) {
                    // 1G01HRY: ITPJCORE:WINNT - method.getExceptionType not in correct format
                    int nameLength = eTypeNames[j].length;
                    char[] convertedName = new char[nameLength + 2];
                    System.arraycopy(eTypeNames[j], 0, convertedName, 1, nameLength);
                    convertedName[0] = 'L';
                    convertedName[nameLength + 1] = ';';
                    this.exceptionTypes[j] = new String(convertedName);
                }
            }
        }
    }
    return this.exceptionTypes;
}

From source file:com.codenvy.ide.ext.java.server.internal.core.BinaryMethod.java

License:Open Source License

/**
 * @see org.eclipse.jdt.core.IMethod#getTypeParameterSignatures()
 * @since 3.0//w w w .jav a  2 s  . co  m
 * @deprecated
 */
public String[] getTypeParameterSignatures() throws JavaModelException {
    IBinaryMethod info = (IBinaryMethod) getElementInfo();
    char[] genericSignature = info.getGenericSignature();
    if (genericSignature == null)
        return CharOperation.NO_STRINGS;
    char[] dotBasedSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.');
    char[][] typeParams = Signature.getTypeParameters(dotBasedSignature);
    return CharOperation.toStrings(typeParams);
}

From source file:com.codenvy.ide.ext.java.server.internal.core.BinaryMethod.java

License:Open Source License

private String getReturnType(IBinaryMethod info) {
    char[] genericSignature = info.getGenericSignature();
    char[] signature = genericSignature == null ? info.getMethodDescriptor() : genericSignature;
    char[] dotBasedSignature = CharOperation.replaceOnCopy(signature, '/', '.');
    String returnTypeName = Signature.getReturnType(new String(dotBasedSignature));
    return new String(ClassFile.translatedName(returnTypeName.toCharArray()));
}

From source file:com.codenvy.ide.ext.java.server.internal.core.ClassFileInfo.java

License:Open Source License

/**
 * Creates the handles and infos for the methods of the given binary type.
 * Adds new handles to the given vector.
 *//*from w  w  w  . j ava 2s  .com*/
private void generateMethodInfos(IType type, IBinaryType typeInfo, HashMap newElements,
        ArrayList childrenHandles, ArrayList typeParameterHandles) {
    IBinaryMethod[] methods = typeInfo.getMethods();
    if (methods == null) {
        return;
    }
    for (int i = 0, methodCount = methods.length; i < methodCount; i++) {
        IBinaryMethod methodInfo = methods[i];
        final boolean isConstructor = methodInfo.isConstructor();
        boolean isEnum = false;
        try {
            isEnum = type.isEnum();
        } catch (JavaModelException e) {
            // ignore
        }
        // TODO (jerome) filter out synthetic members
        //                        indexer should not index them as well
        // if ((methodInfo.getModifiers() & IConstants.AccSynthetic) != 0) continue; // skip synthetic
        boolean useGenericSignature = true;
        char[] signature = methodInfo.getGenericSignature();
        String[] pNames = null;
        if (signature == null) {
            useGenericSignature = false;
            signature = methodInfo.getMethodDescriptor();
            if (isEnum && isConstructor) {
                pNames = Signature.getParameterTypes(new String(signature));
                int length = pNames.length - 2;
                if (length >= 0) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=436347
                    System.arraycopy(pNames, 2, pNames = new String[length], 0, length);
            }
        }
        String selector = new String(methodInfo.getSelector());
        if (isConstructor) {
            selector = type.getElementName();
        }
        try {
            if (!(isEnum && isConstructor && !useGenericSignature)) {
                pNames = Signature.getParameterTypes(new String(signature));
            }
            if (isConstructor && useGenericSignature && type.isMember() && !Flags.isStatic(type.getFlags())) {
                int length = pNames.length;
                System.arraycopy(pNames, 0, (pNames = new String[length + 1]), 1, length);
                char[] descriptor = methodInfo.getMethodDescriptor();
                final String[] parameterTypes = Signature.getParameterTypes(new String(descriptor));
                pNames[0] = parameterTypes[0];
            }
        } catch (IllegalArgumentException e) {
            // protect against malformed .class file (e.g. com/sun/crypto/provider/SunJCE_b.class has a 'a' generic signature)
            signature = methodInfo.getMethodDescriptor();
            pNames = Signature.getParameterTypes(new String(signature));
        } catch (JavaModelException e) {
            // protect against malformed .class file (e.g. com/sun/crypto/provider/SunJCE_b.class has a 'a' generic signature)
            signature = methodInfo.getMethodDescriptor();
            pNames = Signature.getParameterTypes(new String(signature));
        }
        char[][] paramNames = new char[pNames.length][];
        for (int j = 0; j < pNames.length; j++) {
            paramNames[j] = pNames[j].toCharArray();
        }
        char[][] parameterTypes = ClassFile.translatedNames(paramNames);
        JavaModelManager manager = ((JavaElement) type).manager;
        selector = manager.intern(selector);
        for (int j = 0; j < pNames.length; j++) {
            pNames[j] = manager.intern(new String(parameterTypes[j]));
        }
        BinaryMethod method = new BinaryMethod((JavaElement) type, manager, selector, pNames);
        childrenHandles.add(method);

        // ensure that 2 binary methods with the same signature but with different return types have different occurrence counts.
        // (case of bridge methods in 1.5)
        while (newElements.containsKey(method))
            method.occurrenceCount++;

        newElements.put(method, methodInfo);

        int max = pNames.length;
        char[][] argumentNames = methodInfo.getArgumentNames();
        if (argumentNames == null || argumentNames.length < max) {
            argumentNames = new char[max][];
            for (int j = 0; j < max; j++) {
                argumentNames[j] = ("arg" + j).toCharArray(); //$NON-NLS-1$
            }
        }
        int startIndex = 0;
        try {
            if (isConstructor) {
                if (isEnum) {
                    startIndex = 2;
                } else if (type.isMember() && !Flags.isStatic(type.getFlags())) {
                    startIndex = 1;
                }
            }
        } catch (JavaModelException e) {
            // ignore
        }
        //      for (int j = startIndex; j < max; j++) {
        //         IBinaryAnnotation[] parameterAnnotations = methodInfo.getParameterAnnotations(j - startIndex);
        //         if (parameterAnnotations != null) {
        //            LocalVariable localVariable = new LocalVariable(
        //                  method,
        //                  new String(argumentNames[j]),
        //                  0,
        //                  -1,
        //                  0,
        //                  -1,
        //                  method.parameterTypes[j],
        //                  null,
        //                  -1,
        //                  true);
        //            generateAnnotationsInfos(localVariable, argumentNames[j], parameterAnnotations, methodInfo.getTagBits(), newElements);
        //         }
        //      }
        generateTypeParameterInfos(method, signature, newElements, typeParameterHandles);
        generateAnnotationsInfos(method, methodInfo.getAnnotations(), methodInfo.getTagBits(), newElements);
        Object defaultValue = methodInfo.getDefaultValue();
        if (defaultValue instanceof IBinaryAnnotation) {
            generateAnnotationInfo(method, newElements, (IBinaryAnnotation) defaultValue,
                    new String(methodInfo.getSelector()));
        }
    }
}

From source file:com.codenvy.ide.ext.java.server.internal.core.JavadocContents.java

License:Open Source License

private String computeMethodAnchorPrefixEnd(BinaryMethod method) throws JavaModelException {
    String typeQualifiedName = null;
    if (this.type.isMember()) {
        IType currentType = this.type;
        StringBuffer buffer = new StringBuffer();
        while (currentType != null) {
            buffer.insert(0, currentType.getElementName());
            currentType = currentType.getDeclaringType();
            if (currentType != null) {
                buffer.insert(0, '.');
            }/*from   ww w. j a  v  a  2  s.c  o m*/
        }
        typeQualifiedName = new String(buffer.toString());
    } else {
        typeQualifiedName = this.type.getElementName();
    }

    String methodName = method.getElementName();
    if (method.isConstructor()) {
        methodName = typeQualifiedName;
    }
    IBinaryMethod info = (IBinaryMethod) method.getElementInfo();

    char[] genericSignature = info.getGenericSignature();
    String anchor = null;
    if (genericSignature != null) {
        genericSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.');
        anchor = Util.toAnchor(0, genericSignature, methodName, Flags.isVarargs(method.getFlags()));
        if (anchor == null)
            throw new JavaModelException(
                    new JavaModelStatus(IJavaModelStatusConstants.UNKNOWN_JAVADOC_FORMAT, method));
    } else {
        anchor = Signature.toString(method.getSignature().replace('/', '.'), methodName, null, true, false,
                Flags.isVarargs(method.getFlags()));
    }
    IType declaringType = this.type;
    if (declaringType.isMember()) {
        // might need to remove a part of the signature corresponding to the synthetic argument (only for constructor)
        if (method.isConstructor() && !Flags.isStatic(declaringType.getFlags())) {
            int indexOfOpeningParen = anchor.indexOf('(');
            if (indexOfOpeningParen == -1) {
                // should not happen as this is a method signature
                return null;
            }
            int index = indexOfOpeningParen;
            indexOfOpeningParen++;
            int indexOfComma = anchor.indexOf(',', index);
            if (indexOfComma != -1) {
                index = indexOfComma + 2;
            } else {
                // no argument, but a synthetic argument
                index = anchor.indexOf(')', index);
            }
            anchor = anchor.substring(0, indexOfOpeningParen) + anchor.substring(index);
        }
    }
    return anchor + JavadocConstants.ANCHOR_PREFIX_END;
}

From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.ClassFileMatchLocator.java

License:Open Source License

/**
 * Locate declaration in the current class file. This class file is always in a jar.
 *///from w  ww  .  j  a  v a2s.  co  m
public void locateMatches(MatchLocator locator, ClassFile classFile, IBinaryType info) throws CoreException {
    SearchPattern pattern = locator.pattern;

    // check annotations references
    matchAnnotations(pattern, locator, classFile, info);

    // check class definition
    BinaryType binaryType = (BinaryType) classFile.getType();
    if (matchBinary(pattern, info, null)) {
        binaryType = new ResolvedBinaryType((JavaElement) binaryType.getParent(), binaryType.getElementName(),
                binaryType.getKey());
        locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE);
        return;
    }

    // Define arrays to store methods/fields from binary type if necessary
    IBinaryMethod[] binaryMethods = info.getMethods();
    int bMethodsLength = binaryMethods == null ? 0 : binaryMethods.length;
    IBinaryMethod[] unresolvedMethods = null;
    char[][] binaryMethodSignatures = null;
    boolean hasUnresolvedMethods = false;

    // Get fields from binary type info
    IBinaryField[] binaryFields = info.getFields();
    int bFieldsLength = binaryFields == null ? 0 : binaryFields.length;
    IBinaryField[] unresolvedFields = null;
    boolean hasUnresolvedFields = false;

    // Report as many accurate matches as possible
    int accuracy = SearchMatch.A_ACCURATE;
    boolean mustResolve = pattern.mustResolve;
    if (mustResolve) {
        BinaryTypeBinding binding = locator.cacheBinaryType(binaryType, info);
        if (binding != null) {
            // filter out element not in hierarchy scope
            if (!locator.typeInHierarchy(binding))
                return;

            // Search matches on resolved methods
            MethodBinding[] availableMethods = binding.availableMethods();
            int aMethodsLength = availableMethods == null ? 0 : availableMethods.length;
            hasUnresolvedMethods = bMethodsLength != aMethodsLength;
            for (int i = 0; i < aMethodsLength; i++) {
                MethodBinding method = availableMethods[i];
                char[] methodSignature = method.genericSignature();
                if (methodSignature == null)
                    methodSignature = method.signature();

                // Report the match if possible
                int level = locator.patternLocator.resolveLevel(method);
                if (level != PatternLocator.IMPOSSIBLE_MATCH) {
                    IMethod methodHandle = binaryType.getMethod(
                            new String(method.isConstructor()
                                    ? binding.compoundName[binding.compoundName.length - 1]
                                    : method.selector),
                            CharOperation.toStrings(
                                    Signature.getParameterTypes(convertClassFileFormat(methodSignature))));
                    accuracy = level == PatternLocator.ACCURATE_MATCH ? SearchMatch.A_ACCURATE
                            : SearchMatch.A_INACCURATE;
                    locator.reportBinaryMemberDeclaration(null, methodHandle, method, info, accuracy);
                }

                // Remove method from unresolved list
                if (hasUnresolvedMethods) {
                    if (binaryMethodSignatures == null) { // Store binary method signatures to avoid multiple computation
                        binaryMethodSignatures = new char[bMethodsLength][];
                        for (int j = 0; j < bMethodsLength; j++) {
                            IBinaryMethod binaryMethod = binaryMethods[j];
                            char[] signature = binaryMethod.getGenericSignature();
                            if (signature == null)
                                signature = binaryMethod.getMethodDescriptor();
                            binaryMethodSignatures[j] = signature;
                        }
                    }
                    for (int j = 0; j < bMethodsLength; j++) {
                        if (CharOperation.equals(binaryMethods[j].getSelector(), method.selector)
                                && CharOperation.equals(binaryMethodSignatures[j], methodSignature)) {
                            if (unresolvedMethods == null) {
                                System.arraycopy(binaryMethods, 0,
                                        unresolvedMethods = new IBinaryMethod[bMethodsLength], 0,
                                        bMethodsLength);
                            }
                            unresolvedMethods[j] = null;
                            break;
                        }
                    }
                }
            }

            // Search matches on resolved fields
            FieldBinding[] availableFields = binding.availableFields();
            int aFieldsLength = availableFields == null ? 0 : availableFields.length;
            hasUnresolvedFields = bFieldsLength != aFieldsLength;
            for (int i = 0; i < aFieldsLength; i++) {
                FieldBinding field = availableFields[i];

                // Report the match if possible
                int level = locator.patternLocator.resolveLevel(field);
                if (level != PatternLocator.IMPOSSIBLE_MATCH) {
                    IField fieldHandle = binaryType.getField(new String(field.name));
                    accuracy = level == PatternLocator.ACCURATE_MATCH ? SearchMatch.A_ACCURATE
                            : SearchMatch.A_INACCURATE;
                    locator.reportBinaryMemberDeclaration(null, fieldHandle, field, info, accuracy);
                }

                // Remove the field from unresolved list
                if (hasUnresolvedFields) {
                    for (int j = 0; j < bFieldsLength; j++) {
                        if (CharOperation.equals(binaryFields[j].getName(), field.name)) {
                            if (unresolvedFields == null) {
                                System.arraycopy(binaryFields, 0,
                                        unresolvedFields = new IBinaryField[bFieldsLength], 0, bFieldsLength);
                            }
                            unresolvedFields[j] = null;
                            break;
                        }
                    }
                }
            }

            // If all methods/fields were accurate then returns now
            if (!hasUnresolvedMethods && !hasUnresolvedFields) {
                return;
            }
        }
        accuracy = SearchMatch.A_INACCURATE;
    }

    // Report inaccurate methods
    if (mustResolve)
        binaryMethods = unresolvedMethods;
    bMethodsLength = binaryMethods == null ? 0 : binaryMethods.length;
    for (int i = 0; i < bMethodsLength; i++) {
        IBinaryMethod method = binaryMethods[i];
        if (method == null)
            continue; // impossible match or already reported as accurate
        if (matchBinary(pattern, method, info)) {
            char[] name;
            if (method.isConstructor()) {
                // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329727
                // We don't need the enclosing type name for the constructor name
                name = info.getSourceName();
            } else {
                name = method.getSelector();
            }
            String selector = new String(name);
            char[] methodSignature = binaryMethodSignatures == null ? null : binaryMethodSignatures[i];
            if (methodSignature == null) {
                methodSignature = method.getGenericSignature();
                if (methodSignature == null)
                    methodSignature = method.getMethodDescriptor();
            }
            String[] parameterTypes = CharOperation
                    .toStrings(Signature.getParameterTypes(convertClassFileFormat(methodSignature)));
            IMethod methodHandle = binaryType.getMethod(selector, parameterTypes);
            methodHandle = new ResolvedBinaryMethod(binaryType, selector, parameterTypes,
                    methodHandle.getKey());
            locator.reportBinaryMemberDeclaration(null, methodHandle, null, info, accuracy);
        }
    }

    // Report inaccurate fields
    if (mustResolve)
        binaryFields = unresolvedFields;
    bFieldsLength = binaryFields == null ? 0 : binaryFields.length;
    for (int i = 0; i < bFieldsLength; i++) {
        IBinaryField field = binaryFields[i];
        if (field == null)
            continue; // impossible match or already reported as accurate
        if (matchBinary(pattern, field, info)) {
            String fieldName = new String(field.getName());
            IField fieldHandle = binaryType.getField(fieldName);
            fieldHandle = new ResolvedBinaryField(binaryType, fieldName, fieldHandle.getKey());
            locator.reportBinaryMemberDeclaration(null, fieldHandle, null, info, accuracy);
        }
    }
}

From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.MatchLocator.java

License:Open Source License

IMethod createBinaryMethodHandle(IType type, char[] methodSelector, char[][] argumentTypeNames) {
    ClassFileReader reader = MatchLocator.classFileReader(type);
    if (reader != null) {
        IBinaryMethod[] methods = reader.getMethods();
        if (methods != null) {
            int argCount = argumentTypeNames == null ? 0 : argumentTypeNames.length;
            nextMethod: for (int i = 0, methodsLength = methods.length; i < methodsLength; i++) {
                IBinaryMethod binaryMethod = methods[i];
                char[] selector = binaryMethod.isConstructor() ? type.getElementName().toCharArray()
                        : binaryMethod.getSelector();
                if (CharOperation.equals(selector, methodSelector)) {
                    char[] signature = binaryMethod.getGenericSignature();
                    if (signature == null)
                        signature = binaryMethod.getMethodDescriptor();
                    char[][] parameterTypes = Signature.getParameterTypes(signature);
                    if (argCount != parameterTypes.length)
                        continue nextMethod;
                    if (argumentTypeNames != null) {
                        for (int j = 0; j < argCount; j++) {
                            char[] parameterTypeName = ClassFileMatchLocator
                                    .convertClassFileFormat(parameterTypes[j]);
                            if (!CharOperation.endsWith(
                                    Signature.toCharArray(Signature.getTypeErasure(parameterTypeName)),
                                    CharOperation.replaceOnCopy(argumentTypeNames[j], '$', '.')))
                                continue nextMethod;
                            parameterTypes[j] = parameterTypeName;
                        }// ww w.  ja va2  s . c o m
                    }
                    return (IMethod) createMethodHandle(type, new String(selector),
                            CharOperation.toStrings(parameterTypes));
                }
            }
        }
    }
    return null;
}

From source file:org.eclipse.che.jdt.BinaryTypeConvector.java

License:Open Source License

private static JsonElement toJsonMethod(IBinaryMethod method) {
    JsonObject object = new JsonObject();
    object.addProperty("modifiers", method.getModifiers());
    object.addProperty("constructor", method.isConstructor());
    object.add("argumentNames", toJsonArrayString(method.getArgumentNames()));
    object.add("annotations", toJsonAnnotations(method.getAnnotations()));
    object.add("defaultValue", toJsonDefaultValue(method.getDefaultValue()));
    object.add("exceptionTypeNames", toJsonArrayString(method.getExceptionTypeNames()));
    object.add("genericSignature", method.getGenericSignature() == null ? JsonNull.INSTANCE
            : new JsonPrimitive(new String(method.getGenericSignature())));
    object.add("methodDescriptor", method.getMethodDescriptor() == null ? JsonNull.INSTANCE
            : new JsonPrimitive(new String(method.getMethodDescriptor())));
    object.add("parameterAnnotations", toJsonParameterAnnotations(method));
    object.add("selector", method.getSelector() == null ? JsonNull.INSTANCE
            : new JsonPrimitive(new String(method.getSelector())));
    object.addProperty("tagBits", String.valueOf(method.getTagBits()));
    object.addProperty("clinit", method.isClinit());
    return object;
}

From source file:org.eclipse.che.jdt.internal.core.search.matching.ClassFileMatchLocator.java

License:Open Source License

/**
 * Locate declaration in the current class file. This class file is always in a jar.
 *///w  ww.  j ava2s  .  co m
public void locateMatches(MatchLocator locator, ClassFile classFile, IBinaryType info) throws CoreException {
    SearchPattern pattern = locator.pattern;

    // check annotations references
    matchAnnotations(pattern, locator, classFile, info);

    // check class definition
    BinaryType binaryType = (BinaryType) classFile.getType();
    if (matchBinary(pattern, info, null)) {
        binaryType = new ResolvedBinaryType((JavaElement) binaryType.getParent(), binaryType.getElementName(),
                binaryType.getKey());
        locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE);
        return;
    }

    // Define arrays to store methods/fields from binary type if necessary
    IBinaryMethod[] binaryMethods = info.getMethods();
    int bMethodsLength = binaryMethods == null ? 0 : binaryMethods.length;
    IBinaryMethod[] unresolvedMethods = null;
    char[][] binaryMethodSignatures = null;
    boolean hasUnresolvedMethods = false;

    // Get fields from binary type info
    IBinaryField[] binaryFields = info.getFields();
    int bFieldsLength = binaryFields == null ? 0 : binaryFields.length;
    IBinaryField[] unresolvedFields = null;
    boolean hasUnresolvedFields = false;

    // Report as many accurate matches as possible
    int accuracy = SearchMatch.A_ACCURATE;
    boolean mustResolve = pattern.mustResolve;
    if (mustResolve) {
        BinaryTypeBinding binding = locator.cacheBinaryType(binaryType, info);
        if (binding != null) {
            // filter out element not in hierarchy scope
            if (!locator.typeInHierarchy(binding))
                return;

            // Search matches on resolved methods
            MethodBinding[] availableMethods = binding.availableMethods();
            int aMethodsLength = availableMethods == null ? 0 : availableMethods.length;
            hasUnresolvedMethods = bMethodsLength != aMethodsLength;
            for (int i = 0; i < aMethodsLength; i++) {
                MethodBinding method = availableMethods[i];
                char[] methodSignature = method.genericSignature();
                if (methodSignature == null)
                    methodSignature = method.signature();

                // Report the match if possible
                int level = locator.patternLocator.resolveLevel(method);
                if (level != org.eclipse.jdt.internal.core.search.matching.PatternLocator.IMPOSSIBLE_MATCH) {
                    IMethod methodHandle = binaryType.getMethod(
                            new String(method.isConstructor()
                                    ? binding.compoundName[binding.compoundName.length - 1]
                                    : method.selector),
                            CharOperation.toStrings(
                                    Signature.getParameterTypes(convertClassFileFormat(methodSignature))));
                    accuracy = level == org.eclipse.jdt.internal.core.search.matching.PatternLocator.ACCURATE_MATCH
                            ? SearchMatch.A_ACCURATE
                            : SearchMatch.A_INACCURATE;
                    locator.reportBinaryMemberDeclaration(null, methodHandle, method, info, accuracy);
                }

                // Remove method from unresolved list
                if (hasUnresolvedMethods) {
                    if (binaryMethodSignatures == null) { // Store binary method signatures to avoid multiple computation
                        binaryMethodSignatures = new char[bMethodsLength][];
                        for (int j = 0; j < bMethodsLength; j++) {
                            IBinaryMethod binaryMethod = binaryMethods[j];
                            char[] signature = binaryMethod.getGenericSignature();
                            if (signature == null)
                                signature = binaryMethod.getMethodDescriptor();
                            binaryMethodSignatures[j] = signature;
                        }
                    }
                    for (int j = 0; j < bMethodsLength; j++) {
                        if (CharOperation.equals(binaryMethods[j].getSelector(), method.selector)
                                && CharOperation.equals(binaryMethodSignatures[j], methodSignature)) {
                            if (unresolvedMethods == null) {
                                System.arraycopy(binaryMethods, 0,
                                        unresolvedMethods = new IBinaryMethod[bMethodsLength], 0,
                                        bMethodsLength);
                            }
                            unresolvedMethods[j] = null;
                            break;
                        }
                    }
                }
            }

            // Search matches on resolved fields
            FieldBinding[] availableFields = binding.availableFields();
            int aFieldsLength = availableFields == null ? 0 : availableFields.length;
            hasUnresolvedFields = bFieldsLength != aFieldsLength;
            for (int i = 0; i < aFieldsLength; i++) {
                FieldBinding field = availableFields[i];

                // Report the match if possible
                int level = locator.patternLocator.resolveLevel(field);
                if (level != org.eclipse.jdt.internal.core.search.matching.PatternLocator.IMPOSSIBLE_MATCH) {
                    IField fieldHandle = binaryType.getField(new String(field.name));
                    accuracy = level == PatternLocator.ACCURATE_MATCH ? SearchMatch.A_ACCURATE
                            : SearchMatch.A_INACCURATE;
                    locator.reportBinaryMemberDeclaration(null, fieldHandle, field, info, accuracy);
                }

                // Remove the field from unresolved list
                if (hasUnresolvedFields) {
                    for (int j = 0; j < bFieldsLength; j++) {
                        if (CharOperation.equals(binaryFields[j].getName(), field.name)) {
                            if (unresolvedFields == null) {
                                System.arraycopy(binaryFields, 0,
                                        unresolvedFields = new IBinaryField[bFieldsLength], 0, bFieldsLength);
                            }
                            unresolvedFields[j] = null;
                            break;
                        }
                    }
                }
            }

            // If all methods/fields were accurate then returns now
            if (!hasUnresolvedMethods && !hasUnresolvedFields) {
                return;
            }
        }
        accuracy = SearchMatch.A_INACCURATE;
    }

    // Report inaccurate methods
    if (mustResolve)
        binaryMethods = unresolvedMethods;
    bMethodsLength = binaryMethods == null ? 0 : binaryMethods.length;
    for (int i = 0; i < bMethodsLength; i++) {
        IBinaryMethod method = binaryMethods[i];
        if (method == null)
            continue; // impossible match or already reported as accurate
        if (matchBinary(pattern, method, info)) {
            char[] name;
            if (method.isConstructor()) {
                // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329727
                // We don't need the enclosing type name for the constructor name
                name = info.getSourceName();
            } else {
                name = method.getSelector();
            }
            String selector = new String(name);
            char[] methodSignature = binaryMethodSignatures == null ? null : binaryMethodSignatures[i];
            if (methodSignature == null) {
                methodSignature = method.getGenericSignature();
                if (methodSignature == null)
                    methodSignature = method.getMethodDescriptor();
            }
            String[] parameterTypes = CharOperation
                    .toStrings(Signature.getParameterTypes(convertClassFileFormat(methodSignature)));
            IMethod methodHandle = binaryType.getMethod(selector, parameterTypes);
            methodHandle = new ResolvedBinaryMethod(binaryType, selector, parameterTypes,
                    methodHandle.getKey());
            locator.reportBinaryMemberDeclaration(null, methodHandle, null, info, accuracy);
        }
    }

    // Report inaccurate fields
    if (mustResolve)
        binaryFields = unresolvedFields;
    bFieldsLength = binaryFields == null ? 0 : binaryFields.length;
    for (int i = 0; i < bFieldsLength; i++) {
        IBinaryField field = binaryFields[i];
        if (field == null)
            continue; // impossible match or already reported as accurate
        if (matchBinary(pattern, field, info)) {
            String fieldName = new String(field.getName());
            IField fieldHandle = binaryType.getField(fieldName);
            fieldHandle = new ResolvedBinaryField(binaryType, fieldName, fieldHandle.getKey());
            locator.reportBinaryMemberDeclaration(null, fieldHandle, null, info, accuracy);
        }
    }
}