PageRenderTime 26ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/aspectj-1.6.9/aspectjtools1.6.9/org/aspectj/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 279 lines | 236 code | 20 blank | 23 comment | 102 complexity | 6d17786971cb17bfa7d84137ceffda93 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2000, 2007 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. *******************************************************************************/
  11. package org.aspectj.org.eclipse.jdt.internal.core.search.matching;
  12. import org.eclipse.core.runtime.CoreException;
  13. import org.aspectj.org.eclipse.jdt.core.*;
  14. import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
  15. import org.aspectj.org.eclipse.jdt.core.search.*;
  16. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  17. import org.aspectj.org.eclipse.jdt.internal.compiler.env.*;
  18. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.*;
  19. import org.aspectj.org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
  20. import org.aspectj.org.eclipse.jdt.internal.core.*;
  21. import org.aspectj.org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
  22. public class ClassFileMatchLocator implements IIndexConstants {
  23. public static char[] convertClassFileFormat(char[] name) {
  24. return CharOperation.replaceOnCopy(name, '/', '.');
  25. }
  26. private boolean checkDeclaringType(IBinaryType enclosingBinaryType, char[] simpleName, char[] qualification, boolean isCaseSensitive, boolean isCamelCase) {
  27. if (simpleName == null && qualification == null) return true;
  28. if (enclosingBinaryType == null) return true;
  29. char[] declaringTypeName = convertClassFileFormat(enclosingBinaryType.getName());
  30. return checkTypeName(simpleName, qualification, declaringTypeName, isCaseSensitive, isCamelCase);
  31. }
  32. private boolean checkParameters(char[] methodDescriptor, char[][] parameterSimpleNames, char[][] parameterQualifications, boolean isCaseSensitive, boolean isCamelCase) {
  33. char[][] arguments = Signature.getParameterTypes(methodDescriptor);
  34. int parameterCount = parameterSimpleNames.length;
  35. if (parameterCount != arguments.length) return false;
  36. for (int i = 0; i < parameterCount; i++)
  37. if (!checkTypeName(parameterSimpleNames[i], parameterQualifications[i], Signature.toCharArray(arguments[i]), isCaseSensitive, isCamelCase))
  38. return false;
  39. return true;
  40. }
  41. private boolean checkTypeName(char[] simpleName, char[] qualification, char[] fullyQualifiedTypeName, boolean isCaseSensitive, boolean isCamelCase) {
  42. // NOTE: if case insensitive then simpleName & qualification are assumed to be lowercase
  43. char[] wildcardPattern = PatternLocator.qualifiedPattern(simpleName, qualification);
  44. if (wildcardPattern == null) return true;
  45. return CharOperation.match(wildcardPattern, fullyQualifiedTypeName, isCaseSensitive);
  46. }
  47. /**
  48. * Locate declaration in the current class file. This class file is always in a jar.
  49. */
  50. public void locateMatches(MatchLocator locator, ClassFile classFile, IBinaryType info) throws CoreException {
  51. // check class definition
  52. SearchPattern pattern = locator.pattern;
  53. BinaryType binaryType = (BinaryType) classFile.getType();
  54. if (matchBinary(pattern, info, null)) {
  55. binaryType = new ResolvedBinaryType((JavaElement) binaryType.getParent(), binaryType.getElementName(), binaryType.getKey());
  56. locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE);
  57. }
  58. int accuracy = SearchMatch.A_ACCURATE;
  59. if (((InternalSearchPattern)pattern).mustResolve) {
  60. try {
  61. BinaryTypeBinding binding = locator.cacheBinaryType(binaryType, info);
  62. if (binding != null) {
  63. // filter out element not in hierarchy scope
  64. if (!locator.typeInHierarchy(binding)) return;
  65. MethodBinding[] methods = binding.methods();
  66. for (int i = 0, l = methods.length; i < l; i++) {
  67. MethodBinding method = methods[i];
  68. if (locator.patternLocator.resolveLevel(method) == PatternLocator.ACCURATE_MATCH) {
  69. char[] methodSignature = method.genericSignature();
  70. if (methodSignature == null) methodSignature = method.signature();
  71. IMethod methodHandle = binaryType.getMethod(
  72. new String(method.isConstructor() ? binding.compoundName[binding.compoundName.length-1] : method.selector),
  73. CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(methodSignature))));
  74. locator.reportBinaryMemberDeclaration(null, methodHandle, method, info, SearchMatch.A_ACCURATE);
  75. }
  76. }
  77. FieldBinding[] fields = binding.fields();
  78. for (int i = 0, l = fields.length; i < l; i++) {
  79. FieldBinding field = fields[i];
  80. if (locator.patternLocator.resolveLevel(field) == PatternLocator.ACCURATE_MATCH) {
  81. IField fieldHandle = binaryType.getField(new String(field.name));
  82. locator.reportBinaryMemberDeclaration(null, fieldHandle, field, info, SearchMatch.A_ACCURATE);
  83. }
  84. }
  85. // no need to check binary info since resolve was successful
  86. return;
  87. }
  88. } catch (AbortCompilation e) { // if compilation was aborted it is a problem with the class path
  89. }
  90. // report as a potential match if binary info matches the pattern
  91. accuracy = SearchMatch.A_INACCURATE;
  92. }
  93. IBinaryMethod[] methods = info.getMethods();
  94. if (methods != null) {
  95. for (int i = 0, l = methods.length; i < l; i++) {
  96. IBinaryMethod method = methods[i];
  97. if (matchBinary(pattern, method, info)) {
  98. char[] name;
  99. if (method.isConstructor()) {
  100. name = info.getName();
  101. int lastSlash = CharOperation.lastIndexOf('/', name);
  102. if (lastSlash != -1) {
  103. name = CharOperation.subarray(name, lastSlash+1, name.length);
  104. }
  105. } else {
  106. name = method.getSelector();
  107. }
  108. String selector = new String(name);
  109. String[] parameterTypes = CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(method.getMethodDescriptor())));
  110. IMethod methodHandle = binaryType.getMethod(selector, parameterTypes);
  111. methodHandle = new ResolvedBinaryMethod(binaryType, selector, parameterTypes, methodHandle.getKey());
  112. locator.reportBinaryMemberDeclaration(null, methodHandle, null, info, accuracy);
  113. }
  114. }
  115. }
  116. IBinaryField[] fields = info.getFields();
  117. if (fields != null) {
  118. for (int i = 0, l = fields.length; i < l; i++) {
  119. IBinaryField field = fields[i];
  120. if (matchBinary(pattern, field, info)) {
  121. String fieldName = new String(field.getName());
  122. IField fieldHandle = binaryType.getField(fieldName);
  123. fieldHandle = new ResolvedBinaryField(binaryType, fieldName, fieldHandle.getKey());
  124. locator.reportBinaryMemberDeclaration(null, fieldHandle, null, info, accuracy);
  125. }
  126. }
  127. }
  128. }
  129. /**
  130. * Finds out whether the given binary info matches the search pattern.
  131. * Default is to return false.
  132. */
  133. boolean matchBinary(SearchPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  134. switch (((InternalSearchPattern)pattern).kind) {
  135. case CONSTRUCTOR_PATTERN :
  136. return matchConstructor((ConstructorPattern) pattern, binaryInfo, enclosingBinaryType);
  137. case FIELD_PATTERN :
  138. return matchField((FieldPattern) pattern, binaryInfo, enclosingBinaryType);
  139. case METHOD_PATTERN :
  140. return matchMethod((MethodPattern) pattern, binaryInfo, enclosingBinaryType);
  141. case SUPER_REF_PATTERN :
  142. return matchSuperTypeReference((SuperTypeReferencePattern) pattern, binaryInfo, enclosingBinaryType);
  143. case TYPE_DECL_PATTERN :
  144. return matchTypeDeclaration((TypeDeclarationPattern) pattern, binaryInfo, enclosingBinaryType);
  145. case OR_PATTERN :
  146. SearchPattern[] patterns = ((OrPattern) pattern).patterns;
  147. for (int i = 0, length = patterns.length; i < length; i++)
  148. if (matchBinary(patterns[i], binaryInfo, enclosingBinaryType)) return true;
  149. }
  150. return false;
  151. }
  152. boolean matchConstructor(ConstructorPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  153. if (!pattern.findDeclarations) return false; // only relevant when finding declarations
  154. if (!(binaryInfo instanceof IBinaryMethod)) return false;
  155. IBinaryMethod method = (IBinaryMethod) binaryInfo;
  156. if (!method.isConstructor()) return false;
  157. if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
  158. return false;
  159. if (pattern.parameterSimpleNames != null) {
  160. char[] methodDescriptor = convertClassFileFormat(method.getMethodDescriptor());
  161. if (!checkParameters(methodDescriptor, pattern.parameterSimpleNames, pattern.parameterQualifications, pattern.isCaseSensitive(), pattern.isCamelCase()))
  162. return false;
  163. }
  164. return true;
  165. }
  166. boolean matchField(FieldPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  167. if (!pattern.findDeclarations) return false; // only relevant when finding declarations
  168. if (!(binaryInfo instanceof IBinaryField)) return false;
  169. IBinaryField field = (IBinaryField) binaryInfo;
  170. if (!pattern.matchesName(pattern.name, field.getName())) return false;
  171. if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
  172. return false;
  173. char[] fieldTypeSignature = Signature.toCharArray(convertClassFileFormat(field.getTypeName()));
  174. return checkTypeName(pattern.typeSimpleName, pattern.typeQualification, fieldTypeSignature, pattern.isCaseSensitive(), pattern.isCamelCase());
  175. }
  176. boolean matchMethod(MethodPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  177. if (!pattern.findDeclarations) return false; // only relevant when finding declarations
  178. if (!(binaryInfo instanceof IBinaryMethod)) return false;
  179. IBinaryMethod method = (IBinaryMethod) binaryInfo;
  180. if (!pattern.matchesName(pattern.selector, method.getSelector())) return false;
  181. if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
  182. return false;
  183. // look at return type only if declaring type is not specified
  184. boolean checkReturnType = pattern.declaringSimpleName == null && (pattern.returnSimpleName != null || pattern.returnQualification != null);
  185. boolean checkParameters = pattern.parameterSimpleNames != null;
  186. if (checkReturnType || checkParameters) {
  187. char[] methodDescriptor = convertClassFileFormat(method.getMethodDescriptor());
  188. if (checkReturnType) {
  189. char[] returnTypeSignature = Signature.toCharArray(Signature.getReturnType(methodDescriptor));
  190. if (!checkTypeName(pattern.returnSimpleName, pattern.returnQualification, returnTypeSignature, pattern.isCaseSensitive(), pattern.isCamelCase()))
  191. return false;
  192. }
  193. if (checkParameters && !checkParameters(methodDescriptor, pattern.parameterSimpleNames, pattern.parameterQualifications, pattern.isCaseSensitive(), pattern.isCamelCase()))
  194. return false;
  195. }
  196. return true;
  197. }
  198. boolean matchSuperTypeReference(SuperTypeReferencePattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  199. if (!(binaryInfo instanceof IBinaryType)) return false;
  200. IBinaryType type = (IBinaryType) binaryInfo;
  201. if (pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_INTERFACES) {
  202. char[] vmName = type.getSuperclassName();
  203. if (vmName != null) {
  204. char[] superclassName = convertClassFileFormat(vmName);
  205. if (checkTypeName(pattern.superSimpleName, pattern.superQualification, superclassName, pattern.isCaseSensitive(), pattern.isCamelCase()))
  206. return true;
  207. }
  208. }
  209. if (pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_CLASSES) {
  210. char[][] superInterfaces = type.getInterfaceNames();
  211. if (superInterfaces != null) {
  212. for (int i = 0, max = superInterfaces.length; i < max; i++) {
  213. char[] superInterfaceName = convertClassFileFormat(superInterfaces[i]);
  214. if (checkTypeName(pattern.superSimpleName, pattern.superQualification, superInterfaceName, pattern.isCaseSensitive(), pattern.isCamelCase()))
  215. return true;
  216. }
  217. }
  218. }
  219. return false;
  220. }
  221. boolean matchTypeDeclaration(TypeDeclarationPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
  222. if (!(binaryInfo instanceof IBinaryType)) return false;
  223. IBinaryType type = (IBinaryType) binaryInfo;
  224. char[] fullyQualifiedTypeName = convertClassFileFormat(type.getName());
  225. boolean qualifiedPattern = pattern instanceof QualifiedTypeDeclarationPattern;
  226. if (pattern.enclosingTypeNames == null || qualifiedPattern) {
  227. char[] simpleName = (pattern.getMatchMode() == SearchPattern.R_PREFIX_MATCH)
  228. ? CharOperation.concat(pattern.simpleName, IIndexConstants.ONE_STAR)
  229. : pattern.simpleName;
  230. char[] pkg = qualifiedPattern ? ((QualifiedTypeDeclarationPattern)pattern).qualification : pattern.pkg;
  231. if (!checkTypeName(simpleName, pkg, fullyQualifiedTypeName, pattern.isCaseSensitive(), pattern.isCamelCase())) return false;
  232. } else {
  233. char[] enclosingTypeName = CharOperation.concatWith(pattern.enclosingTypeNames, '.');
  234. char[] patternString = pattern.pkg == null
  235. ? enclosingTypeName
  236. : CharOperation.concat(pattern.pkg, enclosingTypeName, '.');
  237. if (!checkTypeName(pattern.simpleName, patternString, fullyQualifiedTypeName, pattern.isCaseSensitive(), pattern.isCamelCase())) return false;
  238. }
  239. int kind = TypeDeclaration.kind(type.getModifiers());
  240. switch (pattern.typeSuffix) {
  241. case CLASS_SUFFIX:
  242. return kind == TypeDeclaration.CLASS_DECL;
  243. case INTERFACE_SUFFIX:
  244. return kind == TypeDeclaration.INTERFACE_DECL;
  245. case ENUM_SUFFIX:
  246. return kind == TypeDeclaration.ENUM_DECL;
  247. case ANNOTATION_TYPE_SUFFIX:
  248. return kind == TypeDeclaration.ANNOTATION_TYPE_DECL;
  249. case CLASS_AND_INTERFACE_SUFFIX:
  250. return kind == TypeDeclaration.CLASS_DECL || kind == TypeDeclaration.INTERFACE_DECL;
  251. case CLASS_AND_ENUM_SUFFIX:
  252. return kind == TypeDeclaration.CLASS_DECL || kind == TypeDeclaration.ENUM_DECL;
  253. case INTERFACE_AND_ANNOTATION_SUFFIX:
  254. return kind == TypeDeclaration.INTERFACE_DECL || kind == TypeDeclaration.ANNOTATION_TYPE_DECL;
  255. case TYPE_SUFFIX: // nothing
  256. }
  257. return true;
  258. }
  259. }