1 11 package org.eclipse.jdt.internal.core.search.matching; 12 13 import org.eclipse.core.runtime.CoreException; 14 import org.eclipse.jdt.core.*; 15 import org.eclipse.jdt.core.compiler.CharOperation; 16 import org.eclipse.jdt.core.search.*; 17 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 18 import org.eclipse.jdt.internal.compiler.env.*; 19 import org.eclipse.jdt.internal.compiler.lookup.*; 20 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; 21 import org.eclipse.jdt.internal.core.*; 22 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants; 23 24 public class ClassFileMatchLocator implements IIndexConstants { 25 26 public static char[] convertClassFileFormat(char[] name) { 27 return CharOperation.replaceOnCopy(name, '/', '.'); 28 } 29 30 private boolean checkDeclaringType(IBinaryType enclosingBinaryType, char[] simpleName, char[] qualification, boolean isCaseSensitive, boolean isCamelCase) { 31 if (simpleName == null && qualification == null) return true; 32 if (enclosingBinaryType == null) return true; 33 34 char[] declaringTypeName = convertClassFileFormat(enclosingBinaryType.getName()); 35 return checkTypeName(simpleName, qualification, declaringTypeName, isCaseSensitive, isCamelCase); 36 } 37 private boolean checkParameters(char[] methodDescriptor, char[][] parameterSimpleNames, char[][] parameterQualifications, boolean isCaseSensitive, boolean isCamelCase) { 38 char[][] arguments = Signature.getParameterTypes(methodDescriptor); 39 int parameterCount = parameterSimpleNames.length; 40 if (parameterCount != arguments.length) return false; 41 for (int i = 0; i < parameterCount; i++) 42 if (!checkTypeName(parameterSimpleNames[i], parameterQualifications[i], Signature.toCharArray(arguments[i]), isCaseSensitive, isCamelCase)) 43 return false; 44 return true; 45 } 46 private boolean checkTypeName(char[] simpleName, char[] qualification, char[] fullyQualifiedTypeName, boolean isCaseSensitive, boolean isCamelCase) { 47 char[] wildcardPattern = PatternLocator.qualifiedPattern(simpleName, qualification); 49 if (wildcardPattern == null) return true; 50 return CharOperation.match(wildcardPattern, fullyQualifiedTypeName, isCaseSensitive); 51 } 52 55 public void locateMatches(MatchLocator locator, ClassFile classFile, IBinaryType info) throws CoreException { 56 SearchPattern pattern = locator.pattern; 58 BinaryType binaryType = (BinaryType) classFile.getType(); 59 if (matchBinary(pattern, info, null)) { 60 binaryType = new ResolvedBinaryType((JavaElement) binaryType.getParent(), binaryType.getElementName(), binaryType.getKey()); 61 locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE); 62 } 63 64 int accuracy = SearchMatch.A_ACCURATE; 65 if (((InternalSearchPattern)pattern).mustResolve) { 66 try { 67 BinaryTypeBinding binding = locator.cacheBinaryType(binaryType, info); 68 if (binding != null) { 69 if (!locator.typeInHierarchy(binding)) return; 71 72 MethodBinding[] methods = binding.methods(); 73 for (int i = 0, l = methods.length; i < l; i++) { 74 MethodBinding method = methods[i]; 75 if (locator.patternLocator.resolveLevel(method) == PatternLocator.ACCURATE_MATCH) { 76 char[] methodSignature = method.genericSignature(); 77 if (methodSignature == null) methodSignature = method.signature(); 78 IMethod methodHandle = binaryType.getMethod( 79 new String (method.isConstructor() ? binding.compoundName[binding.compoundName.length-1] : method.selector), 80 CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(methodSignature)))); 81 locator.reportBinaryMemberDeclaration(null, methodHandle, method, info, SearchMatch.A_ACCURATE); 82 } 83 } 84 85 FieldBinding[] fields = binding.fields(); 86 for (int i = 0, l = fields.length; i < l; i++) { 87 FieldBinding field = fields[i]; 88 if (locator.patternLocator.resolveLevel(field) == PatternLocator.ACCURATE_MATCH) { 89 IField fieldHandle = binaryType.getField(new String (field.name)); 90 locator.reportBinaryMemberDeclaration(null, fieldHandle, field, info, SearchMatch.A_ACCURATE); 91 } 92 } 93 94 return; 96 } 97 } catch (AbortCompilation e) { } 99 accuracy = SearchMatch.A_INACCURATE; 101 } 102 103 IBinaryMethod[] methods = info.getMethods(); 104 if (methods != null) { 105 for (int i = 0, l = methods.length; i < l; i++) { 106 IBinaryMethod method = methods[i]; 107 if (matchBinary(pattern, method, info)) { 108 char[] name; 109 if (method.isConstructor()) { 110 name = info.getName(); 111 int lastSlash = CharOperation.lastIndexOf('/', name); 112 if (lastSlash != -1) { 113 name = CharOperation.subarray(name, lastSlash+1, name.length); 114 } 115 } else { 116 name = method.getSelector(); 117 } 118 String selector = new String (name); 119 String [] parameterTypes = CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(method.getMethodDescriptor()))); 120 IMethod methodHandle = binaryType.getMethod(selector, parameterTypes); 121 methodHandle = new ResolvedBinaryMethod(binaryType, selector, parameterTypes, methodHandle.getKey()); 122 locator.reportBinaryMemberDeclaration(null, methodHandle, null, info, accuracy); 123 } 124 } 125 } 126 127 IBinaryField[] fields = info.getFields(); 128 if (fields != null) { 129 for (int i = 0, l = fields.length; i < l; i++) { 130 IBinaryField field = fields[i]; 131 if (matchBinary(pattern, field, info)) { 132 String fieldName = new String (field.getName()); 133 IField fieldHandle = binaryType.getField(fieldName); 134 fieldHandle = new ResolvedBinaryField(binaryType, fieldName, fieldHandle.getKey()); 135 locator.reportBinaryMemberDeclaration(null, fieldHandle, null, info, accuracy); 136 } 137 } 138 } 139 } 140 144 boolean matchBinary(SearchPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) { 145 switch (((InternalSearchPattern)pattern).kind) { 146 case CONSTRUCTOR_PATTERN : 147 return matchConstructor((ConstructorPattern) pattern, binaryInfo, enclosingBinaryType); 148 case FIELD_PATTERN : 149 return matchField((FieldPattern) pattern, binaryInfo, enclosingBinaryType); 150 case METHOD_PATTERN : 151 return matchMethod((MethodPattern) pattern, binaryInfo, enclosingBinaryType); 152 case SUPER_REF_PATTERN : 153 return matchSuperTypeReference((SuperTypeReferencePattern) pattern, binaryInfo, enclosingBinaryType); 154 case TYPE_DECL_PATTERN : 155 return matchTypeDeclaration((TypeDeclarationPattern) pattern, binaryInfo, enclosingBinaryType); 156 case OR_PATTERN : 157 SearchPattern[] patterns = ((OrPattern) pattern).patterns; 158 for (int i = 0, length = patterns.length; i < length; i++) 159 if (matchBinary(patterns[i], binaryInfo, enclosingBinaryType)) return true; 160 } 161 return false; 162 } 163 boolean matchConstructor(ConstructorPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) { 164 if (!pattern.findDeclarations) return false; if (!(binaryInfo instanceof IBinaryMethod)) return false; 166 167 IBinaryMethod method = (IBinaryMethod) binaryInfo; 168 if (!method.isConstructor()) return false; 169 if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase())) 170 return false; 171 if (pattern.parameterSimpleNames != null) { 172 char[] methodDescriptor = convertClassFileFormat(method.getMethodDescriptor()); 173 if (!checkParameters(methodDescriptor, pattern.parameterSimpleNames, pattern.parameterQualifications, pattern.isCaseSensitive(), pattern.isCamelCase())) 174 return false; 175 } 176 return true; 177 } 178 boolean matchField(FieldPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) { 179 if (!pattern.findDeclarations) return false; if (!(binaryInfo instanceof IBinaryField)) return false; 181 182 IBinaryField field = (IBinaryField) binaryInfo; 183 if (!pattern.matchesName(pattern.name, field.getName())) return false; 184 if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase())) 185 return false; 186 187 char[] fieldTypeSignature = Signature.toCharArray(convertClassFileFormat(field.getTypeName())); 188 return checkTypeName(pattern.typeSimpleName, pattern.typeQualification, fieldTypeSignature, pattern.isCaseSensitive(), pattern.isCamelCase()); 189 } 190 boolean matchMethod(MethodPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) { 191 if (!pattern.findDeclarations) return false; if (!(binaryInfo instanceof IBinaryMethod)) return false; 193 194 IBinaryMethod method = (IBinaryMethod) binaryInfo; 195 if (!pattern.matchesName(pattern.selector, method.getSelector())) return false; 196 if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase())) 197 return false; 198 199 boolean checkReturnType = pattern.declaringSimpleName == null && (pattern.returnSimpleName != null || pattern.returnQualification != null); 201 boolean checkParameters = pattern.parameterSimpleNames != null; 202 if (checkReturnType || checkParameters) { 203 char[] methodDescriptor = convertClassFileFormat(method.getMethodDescriptor()); 204 if (checkReturnType) { 205 char[] returnTypeSignature = Signature.toCharArray(Signature.getReturnType(methodDescriptor)); 206 if (!checkTypeName(pattern.returnSimpleName, pattern.returnQualification, returnTypeSignature, pattern.isCaseSensitive(), pattern.isCamelCase())) 207 return false; 208 } 209 if (checkParameters && !checkParameters(methodDescriptor, pattern.parameterSimpleNames, pattern.parameterQualifications, pattern.isCaseSensitive(), pattern.isCamelCase())) 210 return false; 211 } 212 return true; 213 } 214 boolean matchSuperTypeReference(SuperTypeReferencePattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) { 215 if (!(binaryInfo instanceof IBinaryType)) return false; 216 217 IBinaryType type = (IBinaryType) binaryInfo; 218 if (pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_INTERFACES) { 219 char[] vmName = type.getSuperclassName(); 220 if (vmName != null) { 221 char[] superclassName = convertClassFileFormat(vmName); 222 if (checkTypeName(pattern.superSimpleName, pattern.superQualification, superclassName, pattern.isCaseSensitive(), pattern.isCamelCase())) 223 return true; 224 } 225 } 226 227 if (pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_CLASSES) { 228 char[][] superInterfaces = type.getInterfaceNames(); 229 if (superInterfaces != null) { 230 for (int i = 0, max = superInterfaces.length; i < max; i++) { 231 char[] superInterfaceName = convertClassFileFormat(superInterfaces[i]); 232 if (checkTypeName(pattern.superSimpleName, pattern.superQualification, superInterfaceName, pattern.isCaseSensitive(), pattern.isCamelCase())) 233 return true; 234 } 235 } 236 } 237 return false; 238 } 239 boolean matchTypeDeclaration(TypeDeclarationPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) { 240 if (!(binaryInfo instanceof IBinaryType)) return false; 241 242 IBinaryType type = (IBinaryType) binaryInfo; 243 char[] fullyQualifiedTypeName = convertClassFileFormat(type.getName()); 244 boolean qualifiedPattern = pattern instanceof QualifiedTypeDeclarationPattern; 245 if (pattern.enclosingTypeNames == null || qualifiedPattern) { 246 char[] simpleName = (pattern.getMatchMode() == SearchPattern.R_PREFIX_MATCH) 247 ? CharOperation.concat(pattern.simpleName, IIndexConstants.ONE_STAR) 248 : pattern.simpleName; 249 char[] pkg = qualifiedPattern ? ((QualifiedTypeDeclarationPattern)pattern).qualification : pattern.pkg; 250 if (!checkTypeName(simpleName, pkg, fullyQualifiedTypeName, pattern.isCaseSensitive(), pattern.isCamelCase())) return false; 251 } else { 252 char[] enclosingTypeName = CharOperation.concatWith(pattern.enclosingTypeNames, '.'); 253 char[] patternString = pattern.pkg == null 254 ? enclosingTypeName 255 : CharOperation.concat(pattern.pkg, enclosingTypeName, '.'); 256 if (!checkTypeName(pattern.simpleName, patternString, fullyQualifiedTypeName, pattern.isCaseSensitive(), pattern.isCamelCase())) return false; 257 } 258 259 int kind = TypeDeclaration.kind(type.getModifiers()); 260 switch (pattern.typeSuffix) { 261 case CLASS_SUFFIX: 262 return kind == TypeDeclaration.CLASS_DECL; 263 case INTERFACE_SUFFIX: 264 return kind == TypeDeclaration.INTERFACE_DECL; 265 case ENUM_SUFFIX: 266 return kind == TypeDeclaration.ENUM_DECL; 267 case ANNOTATION_TYPE_SUFFIX: 268 return kind == TypeDeclaration.ANNOTATION_TYPE_DECL; 269 case CLASS_AND_INTERFACE_SUFFIX: 270 return kind == TypeDeclaration.CLASS_DECL || kind == TypeDeclaration.INTERFACE_DECL; 271 case CLASS_AND_ENUM_SUFFIX: 272 return kind == TypeDeclaration.CLASS_DECL || kind == TypeDeclaration.ENUM_DECL; 273 case INTERFACE_AND_ANNOTATION_SUFFIX: 274 return kind == TypeDeclaration.INTERFACE_DECL || kind == TypeDeclaration.ANNOTATION_TYPE_DECL; 275 case TYPE_SUFFIX: } 277 return true; 278 } 279 } 280 | Popular Tags |