<s> 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 ) { char [ ] wildcardPattern = PatternLocator . qualifiedPattern ( simpleName , qualification ) ; if ( wildcardPattern == null ) return true ; return CharOperation . match ( wildcardPattern , fullyQualifiedTypeName , isCaseSensitive ) ; } public void locateMatches ( MatchLocator locator , ClassFile classFile , IBinaryType info ) throws CoreException { SearchPattern pattern = locator . pattern ; matchAnnotations ( pattern , locator , classFile , info ) ; 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 ; } IBinaryMethod [ ] binaryMethods = info . getMethods ( ) ; int bMethodsLength = binaryMethods == null ? 0 : binaryMethods . length ; IBinaryMethod [ ] unresolvedMethods = null ; char [ ] [ ] binaryMethodSignatures = null ; boolean hasUnresolvedMethods = false ; IBinaryField [ ] binaryFields = info . getFields ( ) ; int bFieldsLength = binaryFields == null ? 0 : binaryFields . length ; IBinaryField [ ] unresolvedFields = null ; boolean hasUnresolvedFields = false ; int accuracy = SearchMatch . A_ACCURATE ; boolean mustResolve = pattern . mustResolve ; if ( mustResolve ) { BinaryTypeBinding binding = locator . cacheBinaryType ( binaryType , info ) ; if ( binding != null ) { if ( ! locator . typeInHierarchy ( binding ) ) return ; 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 ( ) ; 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 ) ; } if ( hasUnresolvedMethods ) { if ( binaryMethodSignatures == null ) { 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 ; } } } } 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 ] ; 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 ) ; } 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 ( ! hasUnresolvedMethods && ! hasUnresolvedFields ) { return ; } } accuracy = SearchMatch . A_INACCURATE ; } 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 ; if ( matchBinary ( pattern , method , info ) ) { char [ ] name ; if ( method . isConstructor ( ) ) { 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 ) ; } } 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 ; 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 ) ; } } } private void matchAnnotations ( SearchPattern pattern , MatchLocator locator , ClassFile classFile , IBinaryType binaryType ) throws CoreException { 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 ) ; } default : return ; } TypeReferencePattern typeReferencePattern = ( TypeReferencePattern ) pattern ; 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 ) ; match . setLocalElement ( null ) ; locator . report ( match ) ; } 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 ) ; match . setLocalElement ( null ) ; locator . report ( match ) ; } } } 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 ) ; match . setLocalElement ( null ) ; locator . report ( match ) ; } } } } 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 ; 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 ; 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 ; 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 ; 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 : } return true ; } } </s>