<s> package org . eclipse . jdt . internal . core . search . matching ; import org . eclipse . core . runtime . CoreException ; import org . eclipse . jdt . core . IJavaElement ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . core . search . SearchMatch ; import org . eclipse . jdt . core . search . SearchPattern ; import org . eclipse . jdt . internal . compiler . ast . * ; import org . eclipse . jdt . internal . compiler . lookup . Binding ; import org . eclipse . jdt . internal . compiler . lookup . MethodBinding ; import org . eclipse . jdt . internal . compiler . lookup . ParameterizedGenericMethodBinding ; import org . eclipse . jdt . internal . compiler . lookup . ParameterizedMethodBinding ; import org . eclipse . jdt . internal . compiler . lookup . ParameterizedTypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . TypeBinding ; public class ConstructorLocator extends PatternLocator { protected ConstructorPattern pattern ; public ConstructorLocator ( ConstructorPattern pattern ) { super ( pattern ) ; this . pattern = pattern ; } public int match ( ASTNode node , MatchingNodeSet nodeSet ) { if ( ! this . pattern . findReferences ) return IMPOSSIBLE_MATCH ; if ( ! ( node instanceof ExplicitConstructorCall ) ) return IMPOSSIBLE_MATCH ; if ( ! matchParametersCount ( node , ( ( ExplicitConstructorCall ) node ) . arguments ) ) return IMPOSSIBLE_MATCH ; return nodeSet . addMatch ( node , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; } public int match ( ConstructorDeclaration node , MatchingNodeSet nodeSet ) { int referencesLevel = this . pattern . findReferences ? matchLevelForReferences ( node ) : IMPOSSIBLE_MATCH ; int declarationsLevel = this . pattern . findDeclarations ? matchLevelForDeclarations ( node ) : IMPOSSIBLE_MATCH ; return nodeSet . addMatch ( node , referencesLevel >= declarationsLevel ? referencesLevel : declarationsLevel ) ; } public int match ( Expression node , MatchingNodeSet nodeSet ) { if ( ! this . pattern . findReferences ) return IMPOSSIBLE_MATCH ; if ( ! ( node instanceof AllocationExpression ) ) return IMPOSSIBLE_MATCH ; AllocationExpression allocation = ( AllocationExpression ) node ; char [ ] [ ] typeName = allocation . type . getTypeName ( ) ; if ( this . pattern . declaringSimpleName != null && ! matchesName ( this . pattern . declaringSimpleName , typeName [ typeName . length - 1 ] ) ) return IMPOSSIBLE_MATCH ; if ( ! matchParametersCount ( node , allocation . arguments ) ) return IMPOSSIBLE_MATCH ; return nodeSet . addMatch ( node , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; } public int match ( FieldDeclaration field , MatchingNodeSet nodeSet ) { if ( ! this . pattern . findReferences ) return IMPOSSIBLE_MATCH ; if ( field . type != null || ! ( field . initialization instanceof AllocationExpression ) ) return IMPOSSIBLE_MATCH ; AllocationExpression allocation = ( AllocationExpression ) field . initialization ; if ( field . binding != null && field . binding . declaringClass != null ) { if ( this . pattern . declaringSimpleName != null && ! matchesName ( this . pattern . declaringSimpleName , field . binding . declaringClass . sourceName ( ) ) ) return IMPOSSIBLE_MATCH ; } if ( ! matchParametersCount ( field , allocation . arguments ) ) return IMPOSSIBLE_MATCH ; return nodeSet . addMatch ( field , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; } public int match ( MessageSend msgSend , MatchingNodeSet nodeSet ) { if ( ( msgSend . bits & ASTNode . InsideJavadoc ) == 0 ) return IMPOSSIBLE_MATCH ; if ( this . pattern . declaringSimpleName == null || CharOperation . equals ( msgSend . selector , this . pattern . declaringSimpleName ) ) { return nodeSet . addMatch ( msgSend , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; } return IMPOSSIBLE_MATCH ; } public int match ( TypeDeclaration node , MatchingNodeSet nodeSet ) { if ( ! this . pattern . findReferences ) return IMPOSSIBLE_MATCH ; return nodeSet . addMatch ( node , this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ) ; } protected int matchConstructor ( MethodBinding constructor ) { if ( ! constructor . isConstructor ( ) ) return IMPOSSIBLE_MATCH ; int level = resolveLevelForType ( this . pattern . declaringSimpleName , this . pattern . declaringQualification , constructor . declaringClass ) ; if ( level == IMPOSSIBLE_MATCH ) return IMPOSSIBLE_MATCH ; int parameterCount = this . pattern . parameterCount ; if ( parameterCount > - 1 ) { if ( constructor . parameters == null ) return INACCURATE_MATCH ; if ( parameterCount != constructor . parameters . length ) return IMPOSSIBLE_MATCH ; for ( int i = 0 ; i < parameterCount ; i ++ ) { int newLevel = resolveLevelForType ( this . pattern . parameterSimpleNames [ i ] , this . pattern . parameterQualifications [ i ] , constructor . parameters [ i ] ) ; if ( level > newLevel ) { if ( newLevel == IMPOSSIBLE_MATCH ) { return IMPOSSIBLE_MATCH ; } level = newLevel ; } } } return level ; } protected int matchContainer ( ) { if ( this . pattern . findReferences ) return ALL_CONTAINER ; return CLASS_CONTAINER ; } protected int matchLevelForReferences ( ConstructorDeclaration constructor ) { ExplicitConstructorCall constructorCall = constructor . constructorCall ; if ( constructorCall == null || constructorCall . accessMode != ExplicitConstructorCall . ImplicitSuper ) return IMPOSSIBLE_MATCH ; if ( this . pattern . parameterSimpleNames != null ) { int length = this . pattern . parameterSimpleNames . length ; Expression [ ] args = constructorCall . arguments ; int argsLength = args == null ? 0 : args . length ; if ( length != argsLength ) return IMPOSSIBLE_MATCH ; } return this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ; } protected int matchLevelForDeclarations ( ConstructorDeclaration constructor ) { if ( this . pattern . declaringSimpleName != null && ! matchesName ( this . pattern . declaringSimpleName , constructor . selector ) ) return IMPOSSIBLE_MATCH ; if ( this . pattern . parameterSimpleNames != null ) { int length = this . pattern . parameterSimpleNames . length ; Argument [ ] args = constructor . arguments ; int argsLength = args == null ? 0 : args . length ; if ( length != argsLength ) return IMPOSSIBLE_MATCH ; } if ( this . pattern . hasConstructorArguments ( ) ) { if ( constructor . typeParameters == null || constructor . typeParameters . length != this . pattern . constructorArguments . length ) return IMPOSSIBLE_MATCH ; } return this . pattern . mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH ; } boolean matchParametersCount ( ASTNode node , Expression [ ] args ) { if ( this . pattern . parameterSimpleNames != null && ( ! this . pattern . varargs || ( ( node . bits & ASTNode . InsideJavadoc ) != 0 ) ) ) { int length = this . pattern . parameterCount ; if ( length < 0 ) length = this . pattern . parameterSimpleNames . length ; int argsLength = args == null ? 0 : args . length ; if ( length != argsLength ) { return false ; } } return true ; } protected void matchReportReference ( ASTNode reference , IJavaElement element , Binding elementBinding , int accuracy , MatchLocator locator ) throws CoreException { MethodBinding constructorBinding = null ; boolean isSynthetic = false ; if ( reference instanceof ExplicitConstructorCall ) { ExplicitConstructorCall call = ( ExplicitConstructorCall ) reference ; isSynthetic = call . isImplicitSuper ( ) ; constructorBinding = call . binding ; } else if ( reference instanceof AllocationExpression ) { AllocationExpression alloc = ( AllocationExpression ) reference ; constructorBinding = alloc . binding ; } else if ( reference instanceof TypeDeclaration || reference instanceof FieldDeclaration ) { super . matchReportReference ( reference , element , elementBinding , accuracy , locator ) ; if ( this . match != null ) return ; } this . match = locator . newMethodReferenceMatch ( element , elementBinding , accuracy , - 1 , - 1 , true , isSynthetic , reference ) ; if ( constructorBinding instanceof ParameterizedGenericMethodBinding ) { ParameterizedGenericMethodBinding parameterizedMethodBinding = ( ParameterizedGenericMethodBinding ) constructorBinding ; this . match . setRaw ( parameterizedMethodBinding . isRaw ) ; TypeBinding [ ] typeBindings = parameterizedMethodBinding . isRaw ? null : parameterizedMethodBinding . typeArguments ; updateMatch ( typeBindings , locator , this . pattern . constructorArguments , this . pattern . hasConstructorParameters ( ) ) ; if ( constructorBinding . declaringClass . isParameterizedType ( ) || constructorBinding . declaringClass . isRawType ( ) ) { ParameterizedTypeBinding parameterizedBinding = ( ParameterizedTypeBinding ) constructorBinding . declaringClass ; if ( ! this . pattern . hasTypeArguments ( ) && this . pattern . hasConstructorArguments ( ) || parameterizedBinding . isParameterizedWithOwnVariables ( ) ) { } else if ( this . pattern . hasTypeArguments ( ) && ! this . pattern . hasConstructorArguments ( ) ) { updateMatch ( parameterizedBinding , this . pattern . getTypeArguments ( ) , this . pattern . hasTypeParameters ( ) , 0 , locator ) ; } else { updateMatch ( parameterizedBinding , this . pattern . getTypeArguments ( ) , this . pattern . hasTypeParameters ( ) , 0 , locator ) ; } } else if ( this . pattern . hasTypeArguments ( ) ) { this . match . setRule ( SearchPattern . R_ERASURE_MATCH ) ; } } else if ( constructorBinding instanceof ParameterizedMethodBinding ) { if ( constructorBinding . declaringClass . isParameterizedType ( ) || constructorBinding . declaringClass . isRawType ( ) ) { ParameterizedTypeBinding parameterizedBinding = ( ParameterizedTypeBinding ) constructorBinding . declaringClass ; if ( ! this . pattern . hasTypeArguments ( ) && this . pattern . hasConstructorArguments ( ) ) { updateMatch ( parameterizedBinding , new char [ ] [ ] [ ] { this . pattern . constructorArguments } , this . pattern . hasTypeParameters ( ) , 0 , locator ) ; } else if ( ! parameterizedBinding . isParameterizedWithOwnVariables ( ) ) { updateMatch ( parameterizedBinding , this . pattern . getTypeArguments ( ) , this . pattern . hasTypeParameters ( ) , 0 , locator ) ; } } else if ( this . pattern . hasTypeArguments ( ) ) { this . match . setRule ( SearchPattern . R_ERASURE_MATCH ) ; } } else if ( this . pattern . hasConstructorArguments ( ) ) { this . match . setRule ( SearchPattern . R_ERASURE_MATCH ) ; } if ( this . match . getRule ( ) == 0 ) return ; boolean report = ( this . isErasureMatch && this . match . isErasure ( ) ) || ( this . isEquivalentMatch && this . match . isEquivalent ( ) ) || this . match . isExact ( ) ; if ( ! report ) return ; int offset = reference . sourceStart ; this . match . setOffset ( offset ) ; this . match . setLength ( reference . sourceEnd - offset + 1 ) ; if ( reference instanceof FieldDeclaration ) { FieldDeclaration enumConstant = ( FieldDeclaration ) reference ; if ( enumConstant . initialization instanceof QualifiedAllocationExpression ) { locator . reportAccurateEnumConstructorReference ( this . match , enumConstant , ( QualifiedAllocationExpression ) enumConstant . initialization ) ; return ; } } locator . report ( this . match ) ; } public SearchMatch newDeclarationMatch ( ASTNode reference , IJavaElement element , Binding binding , int accuracy , int length , MatchLocator locator ) { this . match = null ; int offset = reference . sourceStart ; if ( this . pattern . findReferences ) { if ( reference instanceof TypeDeclaration ) { TypeDeclaration type = ( TypeDeclaration ) reference ; AbstractMethodDeclaration [ ] methods = type . methods ; if ( methods != null ) { for ( int i = 0 , max = methods . length ; i < max ; i ++ ) { AbstractMethodDeclaration method = methods [ i ] ; boolean synthetic = method . isDefaultConstructor ( ) && method . sourceStart < type . bodyStart ; this . match = locator . newMethodReferenceMatch ( element , binding , accuracy , offset , length , method . isConstructor ( ) , synthetic , method ) ; } } } else if ( reference instanceof ConstructorDeclaration ) { ConstructorDeclaration constructor = ( ConstructorDeclaration ) reference ; ExplicitConstructorCall call = constructor . constructorCall ; boolean synthetic = call != null && call . isImplicitSuper ( ) ; this . match = locator . newMethodReferenceMatch ( element , binding , accuracy , offset , length , constructor . isConstructor ( ) , synthetic , constructor ) ; } } if ( this . match != null ) { return this . match ; } return locator . newDeclarationMatch ( element , binding , accuracy , reference . sourceStart , length ) ; } public int resolveLevel ( ASTNode node ) { if ( this . pattern . findReferences ) { if ( node instanceof AllocationExpression ) return resolveLevel ( ( AllocationExpression ) node ) ; if ( node instanceof ExplicitConstructorCall ) return resolveLevel ( ( ( ExplicitConstructorCall ) node ) . binding ) ; if ( node instanceof TypeDeclaration ) return resolveLevel ( ( TypeDeclaration ) node ) ; if ( node instanceof FieldDeclaration ) return resolveLevel ( ( FieldDeclaration ) node ) ; if ( node instanceof JavadocMessageSend ) { return resolveLevel ( ( ( JavadocMessageSend ) node ) . binding ) ; } } if ( node instanceof ConstructorDeclaration ) return resolveLevel ( ( ConstructorDeclaration ) node , true ) ; return IMPOSSIBLE_MATCH ; } protected int referenceType ( ) { return IJavaElement . METHOD ; } protected int resolveLevel ( AllocationExpression allocation ) { char [ ] [ ] typeName = allocation . type . getTypeName ( ) ; if ( this . pattern . declaringSimpleName != null && ! matchesName ( this . pattern . declaringSimpleName , typeName [ typeName . length - 1 ] ) ) return IMPOSSIBLE_MATCH ; return resolveLevel ( allocation . binding ) ; } protected int resolveLevel ( FieldDeclaration field ) { if ( field . type != null || field . binding == null ) return IMPOSSIBLE_MATCH ; if ( this . pattern . declaringSimpleName != null && ! matchesName ( this . pattern . declaringSimpleName , field . binding . type . sourceName ( ) ) ) return IMPOSSIBLE_MATCH ; if ( ! ( field . initialization instanceof AllocationExpression ) || field . initialization . resolvedType . isLocalType ( ) ) return IMPOSSIBLE_MATCH ; return resolveLevel ( ( ( AllocationExpression ) field . initialization ) . binding ) ; } public int resolveLevel ( Binding binding ) { if ( binding == null ) return INACCURATE_MATCH ; if ( ! ( binding instanceof MethodBinding ) ) return IMPOSSIBLE_MATCH ; MethodBinding constructor = ( MethodBinding ) binding ; int level = matchConstructor ( constructor ) ; if ( level == IMPOSSIBLE_MATCH ) { if ( constructor != constructor . original ( ) ) { level = matchConstructor ( constructor . original ( ) ) ; } } return level ; } protected int resolveLevel ( ConstructorDeclaration constructor , boolean checkDeclarations ) { int referencesLevel = IMPOSSIBLE_MATCH ; if ( this . pattern . findReferences ) { ExplicitConstructorCall constructorCall = constructor . constructorCall ; if ( constructorCall != null && constructorCall . accessMode == ExplicitConstructorCall . ImplicitSuper ) { int callCount = ( constructorCall . arguments == null ) ? 0 : constructorCall . arguments . length ; int patternCount = ( this . pattern . parameterSimpleNames == null ) ? 0 : this . pattern . parameterSimpleNames . length ; if ( patternCount != callCount ) { referencesLevel = IMPOSSIBLE_MATCH ; } else { referencesLevel = resolveLevel ( constructorCall . binding ) ; if ( referencesLevel == ACCURATE_MATCH ) return ACCURATE_MATCH ; } } } if ( ! checkDeclarations ) return referencesLevel ; int declarationsLevel = this . pattern . findDeclarations ? resolveLevel ( constructor . binding ) : IMPOSSIBLE_MATCH ; return referencesLevel >= declarationsLevel ? referencesLevel : declarationsLevel ; } protected int resolveLevel ( TypeDeclaration type ) { AbstractMethodDeclaration [ ] methods = type . methods ; if ( methods != null ) { for ( int i = 0 , length = methods . length ; i < length ; i ++ ) { AbstractMethodDeclaration method = methods [ i ] ; if ( method . isDefaultConstructor ( ) && method . sourceStart < type . bodyStart ) return resolveLevel ( ( ConstructorDeclaration ) method , false ) ; } } return IMPOSSIBLE_MATCH ; } public String toString ( ) { return "Locator for " + this . pattern . toString ( ) ; } } </s>