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) {
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) {
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) {
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) {
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) {
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) {
SearchPattern[] patterns = ((OrPattern) pattern).patterns; for (int i = 0, length = patterns.length; i < length; i++) { matchAnnotations(patterns[i], locator, classFile, binaryType); 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); 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); 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);
matchAnnotations(pattern, locator, classFile, info); if (matchBinary(pattern, info, null)) { binaryType = new ResolvedBinaryType((JavaElement) binaryType.getParent(), binaryType.getElementName(), binaryType.getKey()); locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE); 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); 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()) { String[] parameterTypes = CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(methodSignature))); IMethod methodHandle = binaryType.getMethod(selector, parameterTypes); methodHandle = new ResolvedBinaryMethod(binaryType, selector, parameterTypes, methodHandle.getKey()); 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);
this.patternLocator.mayBeGeneric = false; // there's no longer generic in class files try { new ClassFileMatchLocator().locateMatches(this, classFile, info);
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) {
IMethod createBinaryMethodHandle(IType type, char[] methodSelector, char[][] argumentTypeNames) { IBinaryType reader = MatchLocator.classFileReader(type); if (reader != null) { IBinaryMethod[] methods = reader.getMethods(); if (methods != null) { int argCount = argumentTypeNames == null ? 0 : argumentTypeNames.length; nextMethod : for (int i = 0, methodsLength = methods.length; i < methodsLength; i++) { IBinaryMethod binaryMethod = methods[i]; char[] selector = binaryMethod.isConstructor() ? type.getElementName().toCharArray() : binaryMethod.getSelector(); if (CharOperation.equals(selector, methodSelector)) { char[] signature = binaryMethod.getGenericSignature(); if (signature == null) signature = binaryMethod.getMethodDescriptor(); char[][] parameterTypes = Signature.getParameterTypes(signature); if (argCount != parameterTypes.length) continue nextMethod; if (argumentTypeNames != null) { for (int j = 0; j < argCount; j++) { char[] parameterTypeName = ClassFileMatchLocator.convertClassFileFormat(parameterTypes[j]); if (!CharOperation.endsWith(Signature.toCharArray(Signature.getTypeErasure(parameterTypeName)), CharOperation.replaceOnCopy(argumentTypeNames[j], '$', '.'))) continue nextMethod; parameterTypes[j] = parameterTypeName; } } return (IMethod) createMethodHandle(type, new String(selector), CharOperation.toStrings(parameterTypes)); } } } } return null; } /*
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 (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern) || checkAnnotationTypeReference(CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY, '.'), pattern)) { return true; if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { return true; if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { return true; if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { return true; if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { return true; if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { return true;
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) {
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) {
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) {
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) {
SearchPattern[] patterns = ((OrPattern) pattern).patterns; for (int i = 0, length = patterns.length; i < length; i++) { matchAnnotations(patterns[i], locator, classFile, binaryType); 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); for (int i = 0, max = methods.length; i < max; i++) { IBinaryMethod 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); for (int i = 0, max = fields.length; i < max; i++) { IBinaryField 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);
matchAnnotations(pattern, locator, classFile, info); if (matchBinary(pattern, info, null)) { binaryType = new ResolvedBinaryType((JavaElement) binaryType.getParent(), binaryType.getElementName(), binaryType.getKey()); locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE); 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); 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()) { String[] parameterTypes = CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(methodSignature))); IMethod methodHandle = binaryType.getMethod(selector, parameterTypes); methodHandle = new ResolvedBinaryMethod(binaryType, selector, parameterTypes, methodHandle.getKey()); 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);
this.patternLocator.mayBeGeneric = false; // there's no longer generic in class files try { new ClassFileMatchLocator().locateMatches(this, classFile, info);
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) {