Package org.eclipse.jdt.internal.core.search.matching

Source Code of org.eclipse.jdt.internal.core.search.matching.ClassFileMatchLocator

/*******************************************************************************
* Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.*;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.FieldInfo;
import org.eclipse.jdt.internal.compiler.classfmt.MethodInfo;
import org.eclipse.jdt.internal.compiler.env.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.core.*;
import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;

public class ClassFileMatchLocator implements IIndexConstants {

private static final long TARGET_ANNOTATION_BITS =
  TagBits.AnnotationForType |
  TagBits.AnnotationForParameter |
  TagBits.AnnotationForPackage |
  TagBits.AnnotationForMethod |
  TagBits.AnnotationForLocalVariable |
  TagBits.AnnotationForField |
  TagBits.AnnotationForConstructor |
  TagBits.AnnotationForAnnotationType;
private static final char[] JAVA_LANG_ANNOTATION_ELEMENTTYPE = CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE, '.');
public static char[] convertClassFileFormat(char[] name) {
  return CharOperation.replaceOnCopy(name, '/', '.');
}

private  boolean checkAnnotation(IBinaryAnnotation annotation, TypeReferencePattern pattern) {
  if (checkTypeName(pattern.simpleName, pattern.qualification, convertClassFileFormat(Signature.toCharArray(annotation.getTypeName())), pattern.isCaseSensitive, pattern.isCamelCase)) {
    return true;
  }
  IBinaryElementValuePair[] valuePairs = annotation.getElementValuePairs();
  if (valuePairs != null) {
    for (int j=0, vpLength=valuePairs.length; j<vpLength; j++) {
      IBinaryElementValuePair valuePair = valuePairs[j];
      Object pairValue = valuePair.getValue();
      if (pairValue instanceof IBinaryAnnotation) {
        if (checkAnnotation((IBinaryAnnotation) pairValue, pattern)) {
          return true;
        }
      }
    }
  }
  return false;
}
private boolean checkAnnotations(TypeReferencePattern pattern, IBinaryAnnotation[] annotations, long tagBits) {
  if (annotations != null) {
    for (int a=0, length=annotations.length; a<length; a++) {
      IBinaryAnnotation annotation = annotations[a];
      if (checkAnnotation(annotation, pattern)) {
        return true;
      }
    }
  }
  if ((tagBits & TagBits.AllStandardAnnotationsMask) != 0 && checkStandardAnnotations(tagBits, pattern)) {
    return true;
  }
  return false;
}
private boolean checkAnnotationTypeReference(char[] fullyQualifiedName, TypeReferencePattern pattern) {
  return checkTypeName(pattern.simpleName, pattern.qualification, fullyQualifiedName, pattern.isCaseSensitive, pattern.isCamelCase);
}
private boolean checkDeclaringType(IBinaryType enclosingBinaryType, char[] simpleName, char[] qualification, boolean isCaseSensitive, boolean isCamelCase) {
  if (simpleName == null && qualification == null) return true;
  if (enclosingBinaryType == null) return true;

  char[] declaringTypeName = convertClassFileFormat(enclosingBinaryType.getName());
  return checkTypeName(simpleName, qualification, declaringTypeName, isCaseSensitive, isCamelCase);
}
private boolean checkParameters(char[] methodDescriptor, char[][] parameterSimpleNames, char[][] parameterQualifications, boolean isCaseSensitive, boolean isCamelCase) {
  char[][] arguments = Signature.getParameterTypes(methodDescriptor);
  int parameterCount = parameterSimpleNames.length;
  if (parameterCount != arguments.length) return false;
  for (int i = 0; i < parameterCount; i++)
    if (!checkTypeName(parameterSimpleNames[i], parameterQualifications[i], Signature.toCharArray(arguments[i]), isCaseSensitive, isCamelCase))
      return false;
  return true;
}
private boolean checkStandardAnnotations(long annotationTagBits, TypeReferencePattern pattern) {
  if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_TARGET;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern) ||
      ((annotationTagBits & TARGET_ANNOTATION_BITS) != 0 && checkAnnotationTypeReference(JAVA_LANG_ANNOTATION_ELEMENTTYPE, pattern))) {
      return true;
    }
  }
  if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTION;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern) ||
      checkAnnotationTypeReference(CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY, '.'), pattern)) {
      return true;
    }
  }
  if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_DEPRECATED;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
      return true;
    }
  }
  if ((annotationTagBits & TagBits.AnnotationDocumented) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
      return true;
    }
  }
  if ((annotationTagBits & TagBits.AnnotationInherited) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_INHERITED;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
      return true;
    }
  }
  if ((annotationTagBits & TagBits.AnnotationOverride) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_OVERRIDE;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
      return true;
    }
  }
  if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_SUPPRESSWARNINGS;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
      return true;
    }
  }
  if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_SAFEVARARGS;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
      return true;
    }
  }
  if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
    char[][] compoundName = TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE;
    if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
      return true;
    }
  }
  return false;
}
private boolean checkTypeName(char[] simpleName, char[] qualification, char[] fullyQualifiedTypeName, boolean isCaseSensitive, boolean isCamelCase) {
  // NOTE: if case insensitive then simpleName & qualification are assumed to be lowercase
  char[] wildcardPattern = PatternLocator.qualifiedPattern(simpleName, qualification);
  if (wildcardPattern == null) return true;
  return CharOperation.match(wildcardPattern, fullyQualifiedTypeName, isCaseSensitive);
}
/**
* Locate declaration in the current class file. This class file is always in a jar.
*/
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);
    }
  }
}
/*
* Look for annotations references
*/
private void matchAnnotations(SearchPattern pattern, MatchLocator locator, ClassFile classFile, IBinaryType binaryType) throws CoreException {
  // Only process TypeReference patterns
  switch (pattern.kind) {
    case TYPE_REF_PATTERN:
      break;
    case OR_PATTERN:
      SearchPattern[] patterns = ((OrPattern) pattern).patterns;
      for (int i = 0, length = patterns.length; i < length; i++) {
        matchAnnotations(patterns[i], locator, classFile, binaryType);
      }
      // $FALL-THROUGH$ - fall through default to return
    default:
      return;
  }
  TypeReferencePattern typeReferencePattern  = (TypeReferencePattern) pattern;

  // Look for references in class annotations
  IBinaryAnnotation[] annotations = binaryType.getAnnotations();
  BinaryType classFileBinaryType = (BinaryType) classFile.getType();
  BinaryTypeBinding binaryTypeBinding = null;
  if (checkAnnotations(typeReferencePattern, annotations, binaryType.getTagBits())) {
    classFileBinaryType = new ResolvedBinaryType((JavaElement) classFileBinaryType.getParent(), classFileBinaryType.getElementName(), classFileBinaryType.getKey());
    TypeReferenceMatch match = new TypeReferenceMatch(classFileBinaryType, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource);
    // TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element
    match.setLocalElement(null);
    locator.report(match);
  }

  // Look for references in methods annotations
  MethodInfo[] methods = (MethodInfo[]) binaryType.getMethods();
  if (methods != null) {
    for (int i = 0, max = methods.length; i < max; i++) {
      MethodInfo method = methods[i];
      if (checkAnnotations(typeReferencePattern, method.getAnnotations(), method.getTagBits())) {
          binaryTypeBinding = locator.cacheBinaryType(classFileBinaryType, binaryType);
          IMethod methodHandle = classFileBinaryType.getMethod(
            new String(method.isConstructor() ? binaryTypeBinding.compoundName[binaryTypeBinding.compoundName.length-1] : method.getSelector()),
            CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(method.getMethodDescriptor()))));
          TypeReferenceMatch match = new TypeReferenceMatch(methodHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource);
          // TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element
          match.setLocalElement(null);
          locator.report(match);
      }
    }
  }

  // Look for references in fields annotations
  FieldInfo[] fields = (FieldInfo[]) binaryType.getFields();
  if (fields != null) {
    for (int i = 0, max = fields.length; i < max; i++) {
      FieldInfo field = fields[i];
      if (checkAnnotations(typeReferencePattern, field.getAnnotations(), field.getTagBits())) {
          IField fieldHandle = classFileBinaryType.getField(new String(field.getName()));
          TypeReferenceMatch match = new TypeReferenceMatch(fieldHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource);
          // TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element
          match.setLocalElement(null);
          locator.report(match);
      }
    }
  }
}
/**
* Finds out whether the given binary info matches the search pattern.
* Default is to return false.
*/
boolean matchBinary(SearchPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  switch (pattern.kind) {
    case CONSTRUCTOR_PATTERN :
      return matchConstructor((ConstructorPattern) pattern, binaryInfo, enclosingBinaryType);
    case FIELD_PATTERN :
      return matchField((FieldPattern) pattern, binaryInfo, enclosingBinaryType);
    case METHOD_PATTERN :
      return matchMethod((MethodPattern) pattern, binaryInfo, enclosingBinaryType);
    case SUPER_REF_PATTERN :
      return matchSuperTypeReference((SuperTypeReferencePattern) pattern, binaryInfo, enclosingBinaryType);
    case TYPE_DECL_PATTERN :
      return matchTypeDeclaration((TypeDeclarationPattern) pattern, binaryInfo, enclosingBinaryType);
    case OR_PATTERN :
      SearchPattern[] patterns = ((OrPattern) pattern).patterns;
      for (int i = 0, length = patterns.length; i < length; i++)
        if (matchBinary(patterns[i], binaryInfo, enclosingBinaryType)) return true;
  }
  return false;
}
boolean matchConstructor(ConstructorPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  if (!pattern.findDeclarations) return false; // only relevant when finding declarations
  if (!(binaryInfo instanceof IBinaryMethod)) return false;

  IBinaryMethod method = (IBinaryMethod) binaryInfo;
  if (!method.isConstructor()) return false;
  if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
    return false;
  if (pattern.parameterSimpleNames != null) {
    char[] methodDescriptor = convertClassFileFormat(method.getMethodDescriptor());
    if (!checkParameters(methodDescriptor, pattern.parameterSimpleNames, pattern.parameterQualifications, pattern.isCaseSensitive(), pattern.isCamelCase()))
      return false;
  }
  return true;
}
boolean matchField(FieldPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  if (!pattern.findDeclarations) return false; // only relevant when finding declarations
  if (!(binaryInfo instanceof IBinaryField)) return false;

  IBinaryField field = (IBinaryField) binaryInfo;
  if (!pattern.matchesName(pattern.name, field.getName())) return false;
  if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
    return false;

  char[] fieldTypeSignature = Signature.toCharArray(convertClassFileFormat(field.getTypeName()));
  return checkTypeName(pattern.typeSimpleName, pattern.typeQualification, fieldTypeSignature, pattern.isCaseSensitive(), pattern.isCamelCase());
}
boolean matchMethod(MethodPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  if (!pattern.findDeclarations) return false; // only relevant when finding declarations
  if (!(binaryInfo instanceof IBinaryMethod)) return false;

  IBinaryMethod method = (IBinaryMethod) binaryInfo;
  if (!pattern.matchesName(pattern.selector, method.getSelector())) return false;
  if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
    return false;

  // look at return type only if declaring type is not specified
  boolean checkReturnType = pattern.declaringSimpleName == null && (pattern.returnSimpleName != null || pattern.returnQualification != null);
  boolean checkParameters = pattern.parameterSimpleNames != null;
  if (checkReturnType || checkParameters) {
    char[] methodDescriptor = convertClassFileFormat(method.getMethodDescriptor());
    if (checkReturnType) {
      char[] returnTypeSignature = Signature.toCharArray(Signature.getReturnType(methodDescriptor));
      if (!checkTypeName(pattern.returnSimpleName, pattern.returnQualification, returnTypeSignature, pattern.isCaseSensitive(), pattern.isCamelCase()))
        return false;
    }
    if (checkParameters &&  !checkParameters(methodDescriptor, pattern.parameterSimpleNames, pattern.parameterQualifications, pattern.isCaseSensitive(), pattern.isCamelCase()))
      return false;
  }
  return true;
}
boolean matchSuperTypeReference(SuperTypeReferencePattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  if (!(binaryInfo instanceof IBinaryType)) return false;

  IBinaryType type = (IBinaryType) binaryInfo;
  if (pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_INTERFACES) {
    char[] vmName = type.getSuperclassName();
    if (vmName != null) {
      char[] superclassName = convertClassFileFormat(vmName);
      if (checkTypeName(pattern.superSimpleName, pattern.superQualification, superclassName, pattern.isCaseSensitive(), pattern.isCamelCase()))
        return true;
    }
  }

  if (pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_CLASSES) {
    char[][] superInterfaces = type.getInterfaceNames();
    if (superInterfaces != null) {
      for (int i = 0, max = superInterfaces.length; i < max; i++) {
        char[] superInterfaceName = convertClassFileFormat(superInterfaces[i]);
        if (checkTypeName(pattern.superSimpleName, pattern.superQualification, superInterfaceName, pattern.isCaseSensitive(), pattern.isCamelCase()))
          return true;
      }
    }
  }
  return false;
}
boolean matchTypeDeclaration(TypeDeclarationPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  if (!(binaryInfo instanceof IBinaryType)) return false;

  IBinaryType type = (IBinaryType) binaryInfo;
  char[] fullyQualifiedTypeName = convertClassFileFormat(type.getName());
  boolean qualifiedPattern = pattern instanceof QualifiedTypeDeclarationPattern;
  if (pattern.enclosingTypeNames == null || qualifiedPattern) {
    char[] simpleName = (pattern.getMatchMode() == SearchPattern.R_PREFIX_MATCH)
      ? CharOperation.concat(pattern.simpleName, IIndexConstants.ONE_STAR)
      : pattern.simpleName;
    char[] pkg = qualifiedPattern ? ((QualifiedTypeDeclarationPattern)pattern).qualification : pattern.pkg;
    if (!checkTypeName(simpleName, pkg, fullyQualifiedTypeName, pattern.isCaseSensitive(), pattern.isCamelCase())) return false;
  } else {
    char[] enclosingTypeName = CharOperation.concatWith(pattern.enclosingTypeNames, '.');
    char[] patternString = pattern.pkg == null
      ? enclosingTypeName
      : CharOperation.concat(pattern.pkg, enclosingTypeName, '.');
    if (!checkTypeName(pattern.simpleName, patternString, fullyQualifiedTypeName, pattern.isCaseSensitive(), pattern.isCamelCase())) return false;
  }

  int kind  = TypeDeclaration.kind(type.getModifiers());
  switch (pattern.typeSuffix) {
    case CLASS_SUFFIX:
      return kind == TypeDeclaration.CLASS_DECL;
    case INTERFACE_SUFFIX:
      return kind == TypeDeclaration.INTERFACE_DECL;
    case ENUM_SUFFIX:
      return kind == TypeDeclaration.ENUM_DECL;
    case ANNOTATION_TYPE_SUFFIX:
      return kind == TypeDeclaration.ANNOTATION_TYPE_DECL;
    case CLASS_AND_INTERFACE_SUFFIX:
      return kind == TypeDeclaration.CLASS_DECL || kind == TypeDeclaration.INTERFACE_DECL;
    case CLASS_AND_ENUM_SUFFIX:
      return kind == TypeDeclaration.CLASS_DECL || kind == TypeDeclaration.ENUM_DECL;
    case INTERFACE_AND_ANNOTATION_SUFFIX:
      return kind == TypeDeclaration.INTERFACE_DECL || kind == TypeDeclaration.ANNOTATION_TYPE_DECL;
    case TYPE_SUFFIX: // nothing
  }
  return true;
}
}
TOP

Related Classes of org.eclipse.jdt.internal.core.search.matching.ClassFileMatchLocator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.