<s> package org . eclipse . jdt . internal . core . search . matching ; import org . eclipse . core . resources . IResource ; import org . eclipse . core . runtime . * ; 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 . * ; import org . eclipse . jdt . internal . compiler . env . IBinaryType ; import org . eclipse . jdt . internal . compiler . lookup . * ; import org . eclipse . jdt . internal . compiler . util . SimpleSet ; import org . eclipse . jdt . internal . core . JavaElement ; public class TypeReferenceLocator extends PatternLocator { protected TypeReferencePattern pattern ; protected boolean isDeclarationOfReferencedTypesPattern ; private final int fineGrain ; public TypeReferenceLocator ( TypeReferencePattern pattern ) { super ( pattern ) ; this . pattern = pattern ; this . fineGrain = pattern == null ? 0 : pattern . fineGrain ; this . isDeclarationOfReferencedTypesPattern = this . pattern instanceof DeclarationOfReferencedTypesPattern ; } protected IJavaElement findElement ( IJavaElement element , int accuracy ) { if ( accuracy != SearchMatch . A_ACCURATE ) return null ; DeclarationOfReferencedTypesPattern declPattern = ( DeclarationOfReferencedTypesPattern ) this . pattern ; while ( element != null && ! declPattern . enclosingElement . equals ( element ) ) element = element . getParent ( ) ; return element ; } protected int fineGrain ( ) { return this . fineGrain ; } public int match ( Annotation node , MatchingNodeSet nodeSet ) { return match ( node . type , nodeSet ) ; } public int match ( ASTNode node , MatchingNodeSet nodeSet ) { if ( ! ( node instanceof ImportReference ) ) return IMPOSSIBLE_MATCH ; return nodeSet . addMatch ( node , matchLevel ( ( ImportReference ) node ) ) ; } public int match ( Reference node , MatchingNodeSet nodeSet ) { if ( ! ( node instanceof NameReference ) ) return IMPOSSIBLE_MATCH ; if ( this . pattern . simpleName == null ) return nodeSet . addMatch ( node , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; if ( node instanceof SingleNameReference ) { if ( matchesName ( this . pattern . simpleName , ( ( SingleNameReference ) node ) . token ) ) return nodeSet . addMatch ( node , POSSIBLE_MATCH ) ; } else { char [ ] [ ] tokens = ( ( QualifiedNameReference ) node ) . tokens ; for ( int i = 0 , max = tokens . length ; i < max ; i ++ ) if ( matchesName ( this . pattern . simpleName , tokens [ i ] ) ) return nodeSet . addMatch ( node , POSSIBLE_MATCH ) ; } return IMPOSSIBLE_MATCH ; } public int match ( TypeReference node , MatchingNodeSet nodeSet ) { if ( this . pattern . simpleName == null ) return nodeSet . addMatch ( node , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; if ( node instanceof SingleTypeReference ) { if ( matchesName ( this . pattern . simpleName , ( ( SingleTypeReference ) node ) . token ) ) return nodeSet . addMatch ( node , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; } else { char [ ] [ ] tokens = ( ( QualifiedTypeReference ) node ) . tokens ; for ( int i = 0 , max = tokens . length ; i < max ; i ++ ) if ( matchesName ( this . pattern . simpleName , tokens [ i ] ) ) return nodeSet . addMatch ( node , POSSIBLE_MATCH ) ; } return IMPOSSIBLE_MATCH ; } protected int matchLevel ( ImportReference importRef ) { if ( this . pattern . qualification == null ) { if ( this . pattern . simpleName == null ) return ACCURATE_MATCH ; char [ ] [ ] tokens = importRef . tokens ; boolean onDemand = ( importRef . bits & ASTNode . OnDemand ) != 0 ; final boolean isStatic = importRef . isStatic ( ) ; if ( ! isStatic && onDemand ) { return IMPOSSIBLE_MATCH ; } int length = tokens . length ; if ( matchesName ( this . pattern . simpleName , tokens [ length - 1 ] ) ) { return ACCURATE_MATCH ; } if ( isStatic && ! onDemand && length > 1 ) { if ( matchesName ( this . pattern . simpleName , tokens [ length - 2 ] ) ) { return ACCURATE_MATCH ; } } } else { char [ ] [ ] tokens = importRef . tokens ; char [ ] qualifiedPattern = this . pattern . simpleName == null ? this . pattern . qualification : CharOperation . concat ( this . pattern . qualification , this . pattern . simpleName , '.' ) ; char [ ] qualifiedTypeName = CharOperation . concatWith ( tokens , '.' ) ; if ( qualifiedPattern == null ) return ACCURATE_MATCH ; if ( qualifiedTypeName == null ) return IMPOSSIBLE_MATCH ; if ( qualifiedTypeName . length == 0 ) { if ( qualifiedPattern . length == 0 ) { return ACCURATE_MATCH ; } return IMPOSSIBLE_MATCH ; } boolean matchFirstChar = ! this . isCaseSensitive || ( qualifiedPattern [ 0 ] == qualifiedTypeName [ 0 ] ) ; switch ( this . matchMode ) { case SearchPattern . R_EXACT_MATCH : case SearchPattern . R_PREFIX_MATCH : if ( CharOperation . prefixEquals ( qualifiedPattern , qualifiedTypeName , this . isCaseSensitive ) ) { return POSSIBLE_MATCH ; } break ; case SearchPattern . R_PATTERN_MATCH : if ( CharOperation . match ( qualifiedPattern , qualifiedTypeName , this . isCaseSensitive ) ) { return POSSIBLE_MATCH ; } break ; case SearchPattern . R_REGEXP_MATCH : break ; case SearchPattern . R_CAMELCASE_MATCH : if ( matchFirstChar && CharOperation . camelCaseMatch ( qualifiedPattern , qualifiedTypeName , false ) ) { return POSSIBLE_MATCH ; } if ( ! this . isCaseSensitive && CharOperation . prefixEquals ( qualifiedPattern , qualifiedTypeName , false ) ) { return POSSIBLE_MATCH ; } break ; case SearchPattern . R_CAMELCASE_SAME_PART_COUNT_MATCH : if ( matchFirstChar && CharOperation . camelCaseMatch ( qualifiedPattern , qualifiedTypeName , true ) ) { return POSSIBLE_MATCH ; } break ; } } return IMPOSSIBLE_MATCH ; } protected void matchLevelAndReportImportRef ( ImportReference importRef , Binding binding , MatchLocator locator ) throws CoreException { Binding refBinding = binding ; if ( importRef . isStatic ( ) ) { if ( binding instanceof FieldBinding ) { FieldBinding fieldBinding = ( FieldBinding ) binding ; if ( ! fieldBinding . isStatic ( ) ) return ; refBinding = fieldBinding . declaringClass ; } else if ( binding instanceof MethodBinding ) { MethodBinding methodBinding = ( MethodBinding ) binding ; if ( ! methodBinding . isStatic ( ) ) return ; refBinding = methodBinding . declaringClass ; } else if ( binding instanceof MemberTypeBinding ) { MemberTypeBinding memberBinding = ( MemberTypeBinding ) binding ; if ( ! memberBinding . isStatic ( ) ) return ; } int level = resolveLevel ( refBinding ) ; if ( level >= INACCURATE_MATCH ) { matchReportImportRef ( importRef , binding , locator . createImportHandle ( importRef ) , level == ACCURATE_MATCH ? SearchMatch . A_ACCURATE : SearchMatch . A_INACCURATE , locator ) ; } return ; } super . matchLevelAndReportImportRef ( importRef , refBinding , locator ) ; } protected void matchReportImportRef ( ImportReference importRef , Binding binding , IJavaElement element , int accuracy , MatchLocator locator ) throws CoreException { if ( this . isDeclarationOfReferencedTypesPattern ) { if ( ( element = findElement ( element , accuracy ) ) != null ) { SimpleSet knownTypes = ( ( DeclarationOfReferencedTypesPattern ) this . pattern ) . knownTypes ; while ( binding instanceof ReferenceBinding ) { ReferenceBinding typeBinding = ( ReferenceBinding ) binding ; reportDeclaration ( typeBinding , 1 , locator , knownTypes ) ; binding = typeBinding . enclosingType ( ) ; } } return ; } if ( this . pattern . hasTypeArguments ( ) && ! this . isEquivalentMatch && ! this . isErasureMatch ) { return ; } if ( ( this . pattern . fineGrain != 0 && ( this . pattern . fineGrain & IJavaSearchConstants . IMPORT_DECLARATION_TYPE_REFERENCE ) == 0 ) ) { return ; } this . match = locator . newTypeReferenceMatch ( element , binding , accuracy , importRef ) ; this . match . setRaw ( true ) ; if ( this . pattern . hasTypeArguments ( ) ) { this . match . setRule ( this . match . getRule ( ) & ( ~ SearchPattern . R_FULL_MATCH ) ) ; } TypeBinding typeBinding = null ; boolean lastButOne = false ; if ( binding instanceof ReferenceBinding ) { typeBinding = ( ReferenceBinding ) binding ; } else if ( binding instanceof FieldBinding ) { typeBinding = ( ( FieldBinding ) binding ) . declaringClass ; lastButOne = importRef . isStatic ( ) && ( ( importRef . bits & ASTNode . OnDemand ) == 0 ) ; } else if ( binding instanceof MethodBinding ) { typeBinding = ( ( MethodBinding ) binding ) . declaringClass ; lastButOne = importRef . isStatic ( ) && ( ( importRef . bits & ASTNode . OnDemand ) == 0 ) ; } if ( typeBinding != null ) { int lastIndex = importRef . tokens . length - 1 ; if ( lastButOne ) { lastIndex -- ; } if ( typeBinding instanceof ProblemReferenceBinding ) { ProblemReferenceBinding pbBinding = ( ProblemReferenceBinding ) typeBinding ; typeBinding = pbBinding . closestMatch ( ) ; lastIndex = pbBinding . compoundName . length - 1 ; } while ( typeBinding != null && lastIndex >= 0 ) { if ( resolveLevelForType ( typeBinding ) != IMPOSSIBLE_MATCH ) { if ( locator . encloses ( element ) ) { long [ ] positions = importRef . sourcePositions ; int index = lastIndex ; if ( this . pattern . qualification != null ) { index = lastIndex - this . pattern . segmentsSize ; } if ( index < 0 ) index = 0 ; int start = ( int ) ( ( positions [ index ] ) >>> 32 ) ; int end = ( int ) positions [ lastIndex ] ; this . match . setOffset ( start ) ; this . match . setLength ( end - start + 1 ) ; locator . report ( this . match ) ; } return ; } lastIndex -- ; typeBinding = typeBinding . enclosingType ( ) ; } } locator . reportAccurateTypeReference ( this . match , importRef , this . pattern . simpleName ) ; } protected void matchReportReference ( ArrayTypeReference arrayRef , IJavaElement element , Binding elementBinding , int accuracy , MatchLocator locator ) throws CoreException { if ( this . pattern . simpleName == null ) { if ( locator . encloses ( element ) ) { int offset = arrayRef . sourceStart ; int length = arrayRef . sourceEnd - offset + 1 ; if ( this . match == null ) { this . match = locator . newTypeReferenceMatch ( element , elementBinding , accuracy , offset , length , arrayRef ) ; } else { this . match . setOffset ( offset ) ; this . match . setLength ( length ) ; } locator . report ( this . match ) ; return ; } } this . match = locator . newTypeReferenceMatch ( element , elementBinding , accuracy , arrayRef ) ; if ( arrayRef . resolvedType != null ) { matchReportReference ( arrayRef , - 1 , arrayRef . resolvedType . leafComponentType ( ) , locator ) ; return ; } locator . reportAccurateTypeReference ( this . match , arrayRef , this . pattern . simpleName ) ; } protected void matchReportReference ( ASTNode reference , IJavaElement element , Binding elementBinding , int accuracy , MatchLocator locator ) throws CoreException { matchReportReference ( reference , element , null , null , elementBinding , accuracy , locator ) ; } protected void matchReportReference ( ASTNode reference , IJavaElement element , IJavaElement localElement , IJavaElement [ ] otherElements , Binding elementBinding , int accuracy , MatchLocator locator ) throws CoreException { if ( this . isDeclarationOfReferencedTypesPattern ) { if ( ( element = findElement ( element , accuracy ) ) != null ) reportDeclaration ( reference , element , locator , ( ( DeclarationOfReferencedTypesPattern ) this . pattern ) . knownTypes ) ; return ; } TypeReferenceMatch refMatch = locator . newTypeReferenceMatch ( element , elementBinding , accuracy , reference ) ; refMatch . setLocalElement ( localElement ) ; refMatch . setOtherElements ( otherElements ) ; this . match = refMatch ; if ( reference instanceof QualifiedNameReference ) matchReportReference ( ( QualifiedNameReference ) reference , element , elementBinding , accuracy , locator ) ; else if ( reference instanceof QualifiedTypeReference ) matchReportReference ( ( QualifiedTypeReference ) reference , element , elementBinding , accuracy , locator ) ; else if ( reference instanceof ArrayTypeReference ) matchReportReference ( ( ArrayTypeReference ) reference , element , elementBinding , accuracy , locator ) ; else { TypeBinding typeBinding = reference instanceof Expression ? ( ( Expression ) reference ) . resolvedType : null ; if ( typeBinding != null ) { matchReportReference ( ( Expression ) reference , - 1 , typeBinding , locator ) ; return ; } locator . report ( this . match ) ; } } protected void matchReportReference ( QualifiedNameReference qNameRef , IJavaElement element , Binding elementBinding , int accuracy , MatchLocator locator ) throws CoreException { Binding binding = qNameRef . binding ; TypeBinding typeBinding = null ; int lastIndex = qNameRef . tokens . length - 1 ; switch ( qNameRef . bits & ASTNode . RestrictiveFlagMASK ) { case Binding . FIELD : typeBinding = qNameRef . actualReceiverType ; lastIndex -= qNameRef . otherBindings == null ? 1 : qNameRef . otherBindings . length + 1 ; break ; case Binding . TYPE : if ( binding instanceof TypeBinding ) typeBinding = ( TypeBinding ) binding ; break ; case Binding . VARIABLE : case Binding . TYPE | Binding . VARIABLE : if ( binding instanceof ProblemReferenceBinding ) { typeBinding = ( TypeBinding ) binding ; } else if ( binding instanceof ProblemFieldBinding ) { typeBinding = qNameRef . actualReceiverType ; lastIndex -= qNameRef . otherBindings == null ? 1 : qNameRef . otherBindings . length + 1 ; } else if ( binding instanceof ProblemBinding ) { typeBinding = ( ( ProblemBinding ) binding ) . searchType ; } break ; } if ( typeBinding instanceof ProblemReferenceBinding ) { ProblemReferenceBinding pbBinding = ( ProblemReferenceBinding ) typeBinding ; typeBinding = pbBinding . closestMatch ( ) ; lastIndex = pbBinding . compoundName . length - 1 ; } if ( this . match == null ) { this . match = locator . newTypeReferenceMatch ( element , elementBinding , accuracy , qNameRef ) ; } if ( typeBinding instanceof ReferenceBinding ) { ReferenceBinding refBinding = ( ReferenceBinding ) typeBinding ; while ( refBinding != null && lastIndex >= 0 ) { if ( resolveLevelForType ( refBinding ) == ACCURATE_MATCH ) { if ( locator . encloses ( element ) ) { long [ ] positions = qNameRef . sourcePositions ; int index = lastIndex ; if ( this . pattern . qualification != null ) { index = lastIndex - this . pattern . segmentsSize ; } if ( index < 0 ) index = 0 ; int start = ( int ) ( ( positions [ index ] ) >>> 32 ) ; int end = ( int ) positions [ lastIndex ] ; this . match . setOffset ( start ) ; this . match . setLength ( end - start + 1 ) ; matchReportReference ( qNameRef , lastIndex , refBinding , locator ) ; } return ; } lastIndex -- ; refBinding = refBinding . enclosingType ( ) ; } } locator . reportAccurateTypeReference ( this . match , qNameRef , this . pattern . simpleName ) ; } protected void matchReportReference ( QualifiedTypeReference qTypeRef , IJavaElement element , Binding elementBinding , int accuracy , MatchLocator locator ) throws CoreException { TypeBinding typeBinding = qTypeRef . resolvedType ; int lastIndex = qTypeRef . tokens . length - 1 ; if ( typeBinding instanceof ArrayBinding ) typeBinding = ( ( ArrayBinding ) typeBinding ) . leafComponentType ; if ( typeBinding instanceof ProblemReferenceBinding ) { ProblemReferenceBinding pbBinding = ( ProblemReferenceBinding ) typeBinding ; typeBinding = pbBinding . closestMatch ( ) ; lastIndex = pbBinding . compoundName . length - 1 ; } if ( this . match == null ) { this . match = locator . newTypeReferenceMatch ( element , elementBinding , accuracy , qTypeRef ) ; } if ( typeBinding instanceof ReferenceBinding ) { ReferenceBinding refBinding = ( ReferenceBinding ) typeBinding ; while ( refBinding != null && lastIndex >= 0 ) { if ( resolveLevelForType ( refBinding ) != IMPOSSIBLE_MATCH ) { if ( locator . encloses ( element ) ) { long [ ] positions = qTypeRef . sourcePositions ; int index = lastIndex ; if ( this . pattern . qualification != null ) { index = lastIndex - this . pattern . segmentsSize ; } if ( index < 0 ) index = 0 ; int start = ( int ) ( ( positions [ index ] ) >>> 32 ) ; int end = ( int ) positions [ lastIndex ] ; this . match . setOffset ( start ) ; this . match . setLength ( end - start + 1 ) ; matchReportReference ( qTypeRef , lastIndex , refBinding , locator ) ; } return ; } lastIndex -- ; refBinding = refBinding . enclosingType ( ) ; } } locator . reportAccurateTypeReference ( this . match , qTypeRef , this . pattern . simpleName ) ; } void matchReportReference ( Expression expr , int lastIndex , TypeBinding refBinding , MatchLocator locator ) throws CoreException { if ( refBinding . isParameterizedType ( ) || refBinding . isRawType ( ) ) { ParameterizedTypeBinding parameterizedBinding = ( ParameterizedTypeBinding ) refBinding ; updateMatch ( parameterizedBinding , this . pattern . getTypeArguments ( ) , this . pattern . hasTypeParameters ( ) , 0 , locator ) ; if ( this . match . getRule ( ) == 0 ) return ; boolean report = ( this . isErasureMatch && this . match . isErasure ( ) ) || ( this . isEquivalentMatch && this . match . isEquivalent ( ) ) || this . match . isExact ( ) ; if ( ! report ) return ; if ( refBinding . isParameterizedType ( ) && this . pattern . hasTypeArguments ( ) ) { TypeReference typeRef = null ; TypeReference [ ] typeArguments = null ; if ( expr instanceof ParameterizedQualifiedTypeReference ) { typeRef = ( ParameterizedQualifiedTypeReference ) expr ; typeArguments = ( ( ParameterizedQualifiedTypeReference ) expr ) . typeArguments [ lastIndex ] ; } else if ( expr instanceof ParameterizedSingleTypeReference ) { typeRef = ( ParameterizedSingleTypeReference ) expr ; typeArguments = ( ( ParameterizedSingleTypeReference ) expr ) . typeArguments ; } if ( typeRef != null ) { locator . reportAccurateParameterizedTypeReference ( this . match , typeRef , lastIndex , typeArguments ) ; return ; } } } else if ( this . pattern . hasTypeArguments ( ) ) { this . match . setRule ( SearchPattern . R_ERASURE_MATCH ) ; } if ( expr instanceof ArrayTypeReference ) { locator . reportAccurateTypeReference ( this . match , expr , this . pattern . simpleName ) ; return ; } if ( refBinding . isLocalType ( ) ) { LocalTypeBinding local = ( LocalTypeBinding ) refBinding . erasure ( ) ; IJavaElement focus = this . pattern . focus ; if ( focus != null && local . enclosingMethod != null && focus . getParent ( ) . getElementType ( ) == IJavaElement . METHOD ) { IMethod method = ( IMethod ) focus . getParent ( ) ; if ( ! CharOperation . equals ( local . enclosingMethod . selector , method . getElementName ( ) . toCharArray ( ) ) ) { return ; } } } if ( this . pattern . simpleName == null ) { this . match . setOffset ( expr . sourceStart ) ; this . match . setLength ( expr . sourceEnd - expr . sourceStart + 1 ) ; } locator . report ( this . match ) ; } protected int referenceType ( ) { return IJavaElement . TYPE ; } protected void reportDeclaration ( ASTNode reference , IJavaElement element , MatchLocator locator , SimpleSet knownTypes ) throws CoreException { int maxType = - 1 ; TypeBinding typeBinding = null ; if ( reference instanceof TypeReference ) { typeBinding = ( ( TypeReference ) reference ) . resolvedType ; maxType = Integer . MAX_VALUE ; } else if ( reference instanceof QualifiedNameReference ) { QualifiedNameReference qNameRef = ( QualifiedNameReference ) reference ; Binding binding = qNameRef . binding ; maxType = qNameRef . tokens . length - 1 ; switch ( qNameRef . bits & ASTNode . RestrictiveFlagMASK ) { case Binding . FIELD : typeBinding = qNameRef . actualReceiverType ; maxType -= qNameRef . otherBindings == null ? 1 : qNameRef . otherBindings . length + 1 ; break ; case Binding . TYPE : if ( binding instanceof TypeBinding ) typeBinding = ( TypeBinding ) binding ; break ; case Binding . VARIABLE : case Binding . TYPE | Binding . VARIABLE : if ( binding instanceof ProblemFieldBinding ) { typeBinding = qNameRef . actualReceiverType ; maxType -= qNameRef . otherBindings == null ? 1 : qNameRef . otherBindings . length + 1 ; } else if ( binding instanceof ProblemBinding ) { ProblemBinding pbBinding = ( ProblemBinding ) binding ; typeBinding = pbBinding . searchType ; char [ ] partialQualifiedName = pbBinding . name ; maxType = CharOperation . occurencesOf ( '.' , partialQualifiedName ) - 1 ; if ( typeBinding == null || maxType < 0 ) return ; } break ; } } else if ( reference instanceof SingleNameReference ) { typeBinding = ( TypeBinding ) ( ( SingleNameReference ) reference ) . binding ; maxType = 1 ; } if ( typeBinding instanceof ArrayBinding ) typeBinding = ( ( ArrayBinding ) typeBinding ) . leafComponentType ; if ( typeBinding == null || typeBinding instanceof BaseTypeBinding ) return ; if ( typeBinding instanceof ProblemReferenceBinding ) { TypeBinding original = typeBinding . closestMatch ( ) ; if ( original == null ) return ; typeBinding = original ; } typeBinding = typeBinding . erasure ( ) ; reportDeclaration ( ( ReferenceBinding ) typeBinding , maxType , locator , knownTypes ) ; } protected void reportDeclaration ( ReferenceBinding typeBinding , int maxType , MatchLocator locator , SimpleSet knownTypes ) throws CoreException { IType type = locator . lookupType ( typeBinding ) ; if ( type == null ) return ; IResource resource = type . getResource ( ) ; boolean isBinary = type . isBinary ( ) ; IBinaryType info = null ; if ( isBinary ) { if ( resource == null ) resource = type . getJavaProject ( ) . getProject ( ) ; info = locator . getBinaryInfo ( ( org . eclipse . jdt . internal . core . ClassFile ) type . getClassFile ( ) , resource ) ; } while ( maxType >= 0 && type != null ) { if ( ! knownTypes . includes ( type ) ) { if ( isBinary ) { locator . reportBinaryMemberDeclaration ( resource , type , typeBinding , info , SearchMatch . A_ACCURATE ) ; } else { if ( typeBinding instanceof ParameterizedTypeBinding ) typeBinding = ( ( ParameterizedTypeBinding ) typeBinding ) . genericType ( ) ; ClassScope scope = ( ( SourceTypeBinding ) typeBinding ) . scope ; if ( scope != null ) { TypeDeclaration typeDecl = scope . referenceContext ; int offset = typeDecl . sourceStart ; this . match = new TypeDeclarationMatch ( ( ( JavaElement ) type ) . resolved ( typeBinding ) , SearchMatch . A_ACCURATE , offset , typeDecl . sourceEnd - offset + 1 , locator . getParticipant ( ) , resource ) ; locator . report ( this . match ) ; } } knownTypes . add ( type ) ; } typeBinding = typeBinding . enclosingType ( ) ; IJavaElement parent = type . getParent ( ) ; if ( parent instanceof IType ) { type = ( IType ) parent ; } else { type = null ; } maxType -- ; } } public int resolveLevel ( ASTNode node ) { if ( node instanceof TypeReference ) return resolveLevel ( ( TypeReference ) node ) ; if ( node instanceof NameReference ) return resolveLevel ( ( NameReference ) node ) ; return IMPOSSIBLE_MATCH ; } public int resolveLevel ( Binding binding ) { if ( binding == null ) return INACCURATE_MATCH ; if ( ! ( binding instanceof TypeBinding ) ) return IMPOSSIBLE_MATCH ; TypeBinding typeBinding = ( TypeBinding ) binding ; if ( typeBinding instanceof ArrayBinding ) typeBinding = ( ( ArrayBinding ) typeBinding ) . leafComponentType ; if ( typeBinding instanceof ProblemReferenceBinding ) typeBinding = ( ( ProblemReferenceBinding ) typeBinding ) . closestMatch ( ) ; return resolveLevelForTypeOrEnclosingTypes ( this . pattern . simpleName , this . pattern . qualification , typeBinding ) ; } protected int resolveLevel ( NameReference nameRef ) { Binding binding = nameRef . binding ; if ( nameRef instanceof SingleNameReference ) { if ( binding instanceof ProblemReferenceBinding ) binding = ( ( ProblemReferenceBinding ) binding ) . closestMatch ( ) ; if ( binding instanceof ReferenceBinding ) return resolveLevelForType ( ( ReferenceBinding ) binding ) ; return binding == null || binding instanceof ProblemBinding ? INACCURATE_MATCH : IMPOSSIBLE_MATCH ; } TypeBinding typeBinding = null ; QualifiedNameReference qNameRef = ( QualifiedNameReference ) nameRef ; switch ( qNameRef . bits & ASTNode . RestrictiveFlagMASK ) { case Binding . FIELD : if ( qNameRef . tokens . length < ( qNameRef . otherBindings == null ? 2 : qNameRef . otherBindings . length + 2 ) ) return IMPOSSIBLE_MATCH ; typeBinding = nameRef . actualReceiverType ; break ; case Binding . LOCAL : return IMPOSSIBLE_MATCH ; case Binding . TYPE : if ( binding instanceof TypeBinding ) typeBinding = ( TypeBinding ) binding ; break ; case Binding . VARIABLE : case Binding . TYPE | Binding . VARIABLE : if ( binding instanceof ProblemReferenceBinding ) { typeBinding = ( TypeBinding ) binding ; } else if ( binding instanceof ProblemFieldBinding ) { if ( qNameRef . tokens . length < ( qNameRef . otherBindings == null ? 2 : qNameRef . otherBindings . length + 2 ) ) return IMPOSSIBLE_MATCH ; typeBinding = nameRef . actualReceiverType ; } else if ( binding instanceof ProblemBinding ) { ProblemBinding pbBinding = ( ProblemBinding ) binding ; if ( CharOperation . occurencesOf ( '.' , pbBinding . name ) <= 0 ) return INACCURATE_MATCH ; typeBinding = pbBinding . searchType ; } break ; } return resolveLevel ( typeBinding ) ; } protected int resolveLevel ( TypeReference typeRef ) { TypeBinding typeBinding = typeRef . resolvedType ; if ( typeBinding instanceof ArrayBinding ) typeBinding = ( ( ArrayBinding ) typeBinding ) . leafComponentType ; if ( typeBinding instanceof ProblemReferenceBinding ) typeBinding = ( ( ProblemReferenceBinding ) typeBinding ) . closestMatch ( ) ; if ( typeRef instanceof SingleTypeReference ) { return resolveLevelForType ( typeBinding ) ; } else return resolveLevelForTypeOrEnclosingTypes ( this . pattern . simpleName , this . pattern . qualification , typeBinding ) ; } protected int resolveLevelForType ( TypeBinding typeBinding ) { if ( typeBinding == null || ! typeBinding . isValidBinding ( ) ) { if ( this . pattern . typeSuffix != TYPE_SUFFIX ) return INACCURATE_MATCH ; } else { switch ( this . pattern . typeSuffix ) { case CLASS_SUFFIX : if ( ! typeBinding . isClass ( ) ) return IMPOSSIBLE_MATCH ; break ; case CLASS_AND_INTERFACE_SUFFIX : if ( ! ( typeBinding . isClass ( ) || ( typeBinding . isInterface ( ) && ! typeBinding . isAnnotationType ( ) ) ) ) return IMPOSSIBLE_MATCH ; break ; case CLASS_AND_ENUM_SUFFIX : if ( ! ( typeBinding . isClass ( ) || typeBinding . isEnum ( ) ) ) return IMPOSSIBLE_MATCH ; break ; case INTERFACE_SUFFIX : if ( ! typeBinding . isInterface ( ) || typeBinding . isAnnotationType ( ) ) return IMPOSSIBLE_MATCH ; break ; case INTERFACE_AND_ANNOTATION_SUFFIX : if ( ! ( typeBinding . isInterface ( ) || typeBinding . isAnnotationType ( ) ) ) return IMPOSSIBLE_MATCH ; break ; case ENUM_SUFFIX : if ( ! typeBinding . isEnum ( ) ) return IMPOSSIBLE_MATCH ; break ; case ANNOTATION_TYPE_SUFFIX : if ( ! typeBinding . isAnnotationType ( ) ) return IMPOSSIBLE_MATCH ; break ; case TYPE_SUFFIX : } } return resolveLevelForType ( this . pattern . simpleName , this . pattern . qualification , this . pattern . getTypeArguments ( ) , 0 , typeBinding ) ; } protected int resolveLevelForTypeOrEnclosingTypes ( char [ ] simpleNamePattern , char [ ] qualificationPattern , TypeBinding binding ) { if ( binding == null ) return INACCURATE_MATCH ; if ( binding instanceof ReferenceBinding ) { ReferenceBinding type = ( ReferenceBinding ) binding ; while ( type != null ) { int level = resolveLevelForType ( type ) ; if ( level != IMPOSSIBLE_MATCH ) return level ; type = type . enclosingType ( ) ; } } return IMPOSSIBLE_MATCH ; } public String toString ( ) { return "Locator for " + this . pattern . toString ( ) ; } } </s>