<s> package org . eclipse . jdt . internal . core . search . matching ; import org . eclipse . core . resources . IResource ; 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 . * ; 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 FieldLocator extends VariableLocator { protected boolean isDeclarationOfAccessedFieldsPattern ; public FieldLocator ( FieldPattern pattern ) { super ( pattern ) ; this . isDeclarationOfAccessedFieldsPattern = this . pattern instanceof DeclarationOfAccessedFieldsPattern ; } protected int fineGrain ( ) { return this . pattern . fineGrain ; } public int match ( ASTNode node , MatchingNodeSet nodeSet ) { int declarationsLevel = IMPOSSIBLE_MATCH ; if ( this . pattern . findReferences ) { if ( node instanceof ImportReference ) { ImportReference importRef = ( ImportReference ) node ; int length = importRef . tokens . length - 1 ; if ( importRef . isStatic ( ) && ( ( importRef . bits & ASTNode . OnDemand ) == 0 ) && matchesName ( this . pattern . name , importRef . tokens [ length ] ) ) { char [ ] [ ] compoundName = new char [ length ] [ ] ; System . arraycopy ( importRef . tokens , 0 , compoundName , 0 , length ) ; FieldPattern fieldPattern = ( FieldPattern ) this . pattern ; char [ ] declaringType = CharOperation . concat ( fieldPattern . declaringQualification , fieldPattern . declaringSimpleName , '.' ) ; if ( matchesName ( declaringType , CharOperation . concatWith ( compoundName , '.' ) ) ) { declarationsLevel = this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ; } } } } return nodeSet . addMatch ( node , declarationsLevel ) ; } public int match ( FieldDeclaration node , MatchingNodeSet nodeSet ) { int referencesLevel = IMPOSSIBLE_MATCH ; if ( this . pattern . findReferences ) if ( this . pattern . writeAccess && ! this . pattern . readAccess && node . initialization != null ) if ( matchesName ( this . pattern . name , node . name ) ) referencesLevel = this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ; int declarationsLevel = IMPOSSIBLE_MATCH ; if ( this . pattern . findDeclarations ) { switch ( node . getKind ( ) ) { case AbstractVariableDeclaration . FIELD : case AbstractVariableDeclaration . ENUM_CONSTANT : if ( matchesName ( this . pattern . name , node . name ) ) if ( matchesTypeReference ( ( ( FieldPattern ) this . pattern ) . typeSimpleName , node . type ) ) declarationsLevel = this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ; break ; } } return nodeSet . addMatch ( node , referencesLevel >= declarationsLevel ? referencesLevel : declarationsLevel ) ; } protected int matchContainer ( ) { if ( this . pattern . findReferences || this . pattern . fineGrain != 0 ) { return ALL_CONTAINER ; } return CLASS_CONTAINER ; } protected int matchField ( FieldBinding field , boolean matchName ) { if ( field == null ) return INACCURATE_MATCH ; if ( matchName && ! matchesName ( this . pattern . name , field . readableName ( ) ) ) return IMPOSSIBLE_MATCH ; FieldPattern fieldPattern = ( FieldPattern ) this . pattern ; ReferenceBinding receiverBinding = field . declaringClass ; if ( receiverBinding == null ) { if ( field == ArrayBinding . ArrayLength ) return fieldPattern . declaringQualification == null && fieldPattern . declaringSimpleName == null ? ACCURATE_MATCH : IMPOSSIBLE_MATCH ; return INACCURATE_MATCH ; } int declaringLevel = resolveLevelForType ( fieldPattern . declaringSimpleName , fieldPattern . declaringQualification , receiverBinding ) ; if ( declaringLevel == IMPOSSIBLE_MATCH ) return IMPOSSIBLE_MATCH ; if ( fieldPattern . declaringSimpleName == null ) return declaringLevel ; FieldBinding fieldBinding = field ; if ( field instanceof ParameterizedFieldBinding ) { fieldBinding = ( ( ParameterizedFieldBinding ) field ) . originalField ; } int typeLevel = resolveLevelForType ( fieldBinding . type ) ; return declaringLevel > typeLevel ? typeLevel : declaringLevel ; } protected void matchLevelAndReportImportRef ( ImportReference importRef , Binding binding , MatchLocator locator ) throws CoreException { if ( importRef . isStatic ( ) && binding instanceof FieldBinding ) { super . matchLevelAndReportImportRef ( importRef , binding , locator ) ; } } protected int matchReference ( Reference node , MatchingNodeSet nodeSet , boolean writeOnlyAccess ) { if ( node instanceof FieldReference ) { if ( matchesName ( this . pattern . name , ( ( FieldReference ) node ) . token ) ) return nodeSet . addMatch ( node , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; return IMPOSSIBLE_MATCH ; } return super . matchReference ( node , nodeSet , writeOnlyAccess ) ; } 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 . isDeclarationOfAccessedFieldsPattern ) { if ( accuracy != SearchMatch . A_ACCURATE ) return ; DeclarationOfAccessedFieldsPattern declPattern = ( DeclarationOfAccessedFieldsPattern ) this . pattern ; while ( element != null && ! declPattern . enclosingElement . equals ( element ) ) element = element . getParent ( ) ; if ( element != null ) { if ( reference instanceof FieldReference ) { reportDeclaration ( ( ( FieldReference ) reference ) . binding , locator , declPattern . knownFields ) ; } else if ( reference instanceof QualifiedNameReference ) { QualifiedNameReference qNameRef = ( QualifiedNameReference ) reference ; Binding nameBinding = qNameRef . binding ; if ( nameBinding instanceof FieldBinding ) reportDeclaration ( ( FieldBinding ) nameBinding , locator , declPattern . knownFields ) ; int otherMax = qNameRef . otherBindings == null ? 0 : qNameRef . otherBindings . length ; for ( int i = 0 ; i < otherMax ; i ++ ) reportDeclaration ( qNameRef . otherBindings [ i ] , locator , declPattern . knownFields ) ; } else if ( reference instanceof SingleNameReference ) { reportDeclaration ( ( FieldBinding ) ( ( SingleNameReference ) reference ) . binding , locator , declPattern . knownFields ) ; } } } else if ( reference instanceof ImportReference ) { ImportReference importRef = ( ImportReference ) reference ; long [ ] positions = importRef . sourcePositions ; int lastIndex = importRef . tokens . length - 1 ; int start = ( int ) ( ( positions [ lastIndex ] ) >>> 32 ) ; int end = ( int ) positions [ lastIndex ] ; this . match = locator . newFieldReferenceMatch ( element , localElement , elementBinding , accuracy , start , end - start + 1 , importRef ) ; locator . report ( this . match ) ; } else if ( reference instanceof FieldReference ) { FieldReference fieldReference = ( FieldReference ) reference ; long position = fieldReference . nameSourcePosition ; int start = ( int ) ( position >>> 32 ) ; int end = ( int ) position ; this . match = locator . newFieldReferenceMatch ( element , localElement , elementBinding , accuracy , start , end - start + 1 , fieldReference ) ; locator . report ( this . match ) ; } else if ( reference instanceof SingleNameReference ) { int offset = reference . sourceStart ; this . match = locator . newFieldReferenceMatch ( element , localElement , elementBinding , accuracy , offset , reference . sourceEnd - offset + 1 , reference ) ; locator . report ( this . match ) ; } else if ( reference instanceof QualifiedNameReference ) { QualifiedNameReference qNameRef = ( QualifiedNameReference ) reference ; int length = qNameRef . tokens . length ; SearchMatch [ ] matches = new SearchMatch [ length ] ; Binding nameBinding = qNameRef . binding ; int indexOfFirstFieldBinding = qNameRef . indexOfFirstFieldBinding > 0 ? qNameRef . indexOfFirstFieldBinding - 1 : 0 ; if ( matchesName ( this . pattern . name , qNameRef . tokens [ indexOfFirstFieldBinding ] ) && ! ( nameBinding instanceof LocalVariableBinding ) ) { FieldBinding fieldBinding = nameBinding instanceof FieldBinding ? ( FieldBinding ) nameBinding : null ; if ( fieldBinding == null ) { matches [ indexOfFirstFieldBinding ] = locator . newFieldReferenceMatch ( element , localElement , elementBinding , accuracy , - 1 , - 1 , reference ) ; } else { switch ( matchField ( fieldBinding , false ) ) { case ACCURATE_MATCH : matches [ indexOfFirstFieldBinding ] = locator . newFieldReferenceMatch ( element , localElement , elementBinding , SearchMatch . A_ACCURATE , - 1 , - 1 , reference ) ; break ; case INACCURATE_MATCH : this . match = locator . newFieldReferenceMatch ( element , localElement , elementBinding , SearchMatch . A_INACCURATE , - 1 , - 1 , reference ) ; if ( fieldBinding . type != null && fieldBinding . type . isParameterizedType ( ) && this . pattern . hasTypeArguments ( ) ) { updateMatch ( ( ParameterizedTypeBinding ) fieldBinding . type , this . pattern . getTypeArguments ( ) , locator ) ; } matches [ indexOfFirstFieldBinding ] = this . match ; break ; } } } for ( int i = indexOfFirstFieldBinding + 1 ; i < length ; i ++ ) { char [ ] token = qNameRef . tokens [ i ] ; if ( matchesName ( this . pattern . name , token ) ) { FieldBinding otherBinding = qNameRef . otherBindings == null ? null : qNameRef . otherBindings [ i - ( indexOfFirstFieldBinding + 1 ) ] ; if ( otherBinding == null ) { matches [ i ] = locator . newFieldReferenceMatch ( element , localElement , elementBinding , accuracy , - 1 , - 1 , reference ) ; } else { switch ( matchField ( otherBinding , false ) ) { case ACCURATE_MATCH : matches [ i ] = locator . newFieldReferenceMatch ( element , localElement , elementBinding , SearchMatch . A_ACCURATE , - 1 , - 1 , reference ) ; break ; case INACCURATE_MATCH : this . match = locator . newFieldReferenceMatch ( element , localElement , elementBinding , SearchMatch . A_INACCURATE , - 1 , - 1 , reference ) ; if ( otherBinding . type != null && otherBinding . type . isParameterizedType ( ) && this . pattern . hasTypeArguments ( ) ) { updateMatch ( ( ParameterizedTypeBinding ) otherBinding . type , this . pattern . getTypeArguments ( ) , locator ) ; } matches [ i ] = this . match ; break ; } } } } locator . reportAccurateFieldReference ( matches , qNameRef ) ; } } protected void updateMatch ( ParameterizedTypeBinding parameterizedBinding , char [ ] [ ] [ ] patternTypeArguments , MatchLocator locator ) { if ( locator . unitScope == null ) return ; updateMatch ( parameterizedBinding , patternTypeArguments , false , 0 , locator ) ; if ( ! this . match . isExact ( ) ) { this . match . setRule ( 0 ) ; } } protected void reportDeclaration ( FieldBinding fieldBinding , MatchLocator locator , SimpleSet knownFields ) throws CoreException { if ( fieldBinding == ArrayBinding . ArrayLength ) return ; ReferenceBinding declaringClass = fieldBinding . declaringClass ; IType type = locator . lookupType ( declaringClass ) ; if ( type == null ) return ; char [ ] bindingName = fieldBinding . name ; IField field = type . getField ( new String ( bindingName ) ) ; if ( knownFields . addIfNotIncluded ( field ) == 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 ) ; locator . reportBinaryMemberDeclaration ( resource , field , fieldBinding , info , SearchMatch . A_ACCURATE ) ; } else { if ( declaringClass instanceof ParameterizedTypeBinding ) declaringClass = ( ( ParameterizedTypeBinding ) declaringClass ) . genericType ( ) ; ClassScope scope = ( ( SourceTypeBinding ) declaringClass ) . scope ; if ( scope != null ) { TypeDeclaration typeDecl = scope . referenceContext ; FieldDeclaration fieldDecl = null ; FieldDeclaration [ ] fieldDecls = typeDecl . fields ; int length = fieldDecls == null ? 0 : fieldDecls . length ; for ( int i = 0 ; i < length ; i ++ ) { if ( CharOperation . equals ( bindingName , fieldDecls [ i ] . name ) ) { fieldDecl = fieldDecls [ i ] ; break ; } } if ( fieldDecl != null ) { int offset = fieldDecl . sourceStart ; this . match = new FieldDeclarationMatch ( ( ( JavaElement ) field ) . resolved ( fieldBinding ) , SearchMatch . A_ACCURATE , offset , fieldDecl . sourceEnd - offset + 1 , locator . getParticipant ( ) , resource ) ; locator . report ( this . match ) ; } } } } protected int referenceType ( ) { return IJavaElement . FIELD ; } public int resolveLevel ( ASTNode possiblelMatchingNode ) { if ( this . pattern . findReferences || this . pattern . fineGrain != 0 ) { if ( possiblelMatchingNode instanceof FieldReference ) return matchField ( ( ( FieldReference ) possiblelMatchingNode ) . binding , true ) ; else if ( possiblelMatchingNode instanceof NameReference ) return resolveLevel ( ( NameReference ) possiblelMatchingNode ) ; } if ( possiblelMatchingNode instanceof FieldDeclaration ) return matchField ( ( ( FieldDeclaration ) possiblelMatchingNode ) . binding , true ) ; return IMPOSSIBLE_MATCH ; } public int resolveLevel ( Binding binding ) { if ( binding == null ) return INACCURATE_MATCH ; if ( ! ( binding instanceof FieldBinding ) ) return IMPOSSIBLE_MATCH ; return matchField ( ( FieldBinding ) binding , true ) ; } protected int resolveLevel ( NameReference nameRef ) { if ( nameRef instanceof SingleNameReference ) return resolveLevel ( nameRef . binding ) ; Binding binding = nameRef . binding ; QualifiedNameReference qNameRef = ( QualifiedNameReference ) nameRef ; FieldBinding fieldBinding = null ; if ( binding instanceof FieldBinding ) { fieldBinding = ( FieldBinding ) binding ; char [ ] bindingName = fieldBinding . name ; int lastDot = CharOperation . lastIndexOf ( '.' , bindingName ) ; if ( lastDot > - 1 ) bindingName = CharOperation . subarray ( bindingName , lastDot + 1 , bindingName . length ) ; if ( matchesName ( this . pattern . name , bindingName ) ) { int level = matchField ( fieldBinding , false ) ; if ( level != IMPOSSIBLE_MATCH ) return level ; } } int otherMax = qNameRef . otherBindings == null ? 0 : qNameRef . otherBindings . length ; for ( int i = 0 ; i < otherMax ; i ++ ) { char [ ] token = qNameRef . tokens [ i + qNameRef . indexOfFirstFieldBinding ] ; if ( matchesName ( this . pattern . name , token ) ) { FieldBinding otherBinding = qNameRef . otherBindings [ i ] ; int level = matchField ( otherBinding , false ) ; if ( level != IMPOSSIBLE_MATCH ) return level ; } } return IMPOSSIBLE_MATCH ; } protected int resolveLevelForType ( TypeBinding typeBinding ) { FieldPattern fieldPattern = ( FieldPattern ) this . pattern ; TypeBinding fieldTypeBinding = typeBinding ; if ( fieldTypeBinding != null && fieldTypeBinding . isParameterizedType ( ) ) { fieldTypeBinding = typeBinding . erasure ( ) ; } return resolveLevelForType ( fieldPattern . typeSimpleName , fieldPattern . typeQualification , fieldPattern . getTypeArguments ( ) , 0 , fieldTypeBinding ) ; } } </s>