PageRenderTime 29ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/plug-ins/helios/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java

https://github.com/vazexqi/CodingSpectator
Java | 452 lines | 316 code | 43 blank | 93 comment | 61 complexity | 6e73cc3b4debf381f482a1ce6ab29c77 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2004, 2009 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.eclipse.jdt.internal.core.search.matching;
  12. import org.eclipse.jdt.core.BindingKey;
  13. import org.eclipse.jdt.core.IJavaElement;
  14. import org.eclipse.jdt.core.IMethod;
  15. import org.eclipse.jdt.core.IType;
  16. import org.eclipse.jdt.core.ITypeParameter;
  17. import org.eclipse.jdt.core.JavaModelException;
  18. import org.eclipse.jdt.core.Signature;
  19. import org.eclipse.jdt.core.compiler.CharOperation;
  20. import org.eclipse.jdt.core.search.IJavaSearchConstants;
  21. import org.eclipse.jdt.core.search.SearchPattern;
  22. import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
  23. import org.eclipse.jdt.internal.core.util.Util;
  24. public class JavaSearchPattern extends SearchPattern implements IIndexConstants {
  25. /*
  26. * Whether this pattern is case sensitive.
  27. */
  28. boolean isCaseSensitive;
  29. /*
  30. * Whether this pattern is camel case.
  31. */
  32. boolean isCamelCase;
  33. /**
  34. * One of following pattern value:
  35. * <ul>
  36. * <li>{@link #R_EXACT_MATCH}</li>
  37. * <li>{@link #R_PREFIX_MATCH}</li>
  38. * <li>{@link #R_PATTERN_MATCH}</li>
  39. * <li>{@link #R_REGEXP_MATCH}</li>
  40. * <li>{@link #R_CAMELCASE_MATCH}</li>
  41. * <li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}</li>
  42. * </ul>
  43. */
  44. int matchMode;
  45. /**
  46. * One of {@link #R_ERASURE_MATCH}, {@link #R_EQUIVALENT_MATCH}, {@link #R_FULL_MATCH}.
  47. */
  48. int matchCompatibility;
  49. /**
  50. * Fine grain limitation
  51. */
  52. public int fineGrain= 0;
  53. /**
  54. * Mask used on match rule for match mode.
  55. */
  56. public static final int MATCH_MODE_MASK= R_EXACT_MATCH
  57. | R_PREFIX_MATCH
  58. | R_PATTERN_MATCH
  59. | R_REGEXP_MATCH
  60. | R_CAMELCASE_MATCH
  61. | R_CAMELCASE_SAME_PART_COUNT_MATCH;
  62. /**
  63. * Mask used on match rule for generic relevance.
  64. */
  65. public static final int MATCH_COMPATIBILITY_MASK= R_ERASURE_MATCH | R_EQUIVALENT_MATCH | R_FULL_MATCH;
  66. // Signatures and arguments for parameterized types search
  67. char[][] typeSignatures;
  68. private char[][][] typeArguments;
  69. private int flags= 0;
  70. static final int HAS_TYPE_ARGUMENTS= 1;
  71. protected JavaSearchPattern(int patternKind, int matchRule) {
  72. super(matchRule);
  73. this.kind= patternKind;
  74. // Use getMatchRule() instead of matchRule as super constructor may modify its value
  75. // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=81377
  76. int rule= getMatchRule();
  77. this.isCaseSensitive= (rule & R_CASE_SENSITIVE) != 0;
  78. this.isCamelCase= (rule & (R_CAMELCASE_MATCH | R_CAMELCASE_SAME_PART_COUNT_MATCH)) != 0;
  79. this.matchCompatibility= rule & MATCH_COMPATIBILITY_MASK;
  80. this.matchMode= rule & MATCH_MODE_MASK;
  81. }
  82. /**
  83. * @param fineGrain
  84. */
  85. public static String getFineGrainFlagString(final int fineGrain) {
  86. if (fineGrain == 0) {
  87. return "none"; //$NON-NLS-1$
  88. }
  89. StringBuffer buffer= new StringBuffer();
  90. for (int i= 1; i <= 32; i++) {
  91. int bit= fineGrain & (1 << (i - 1));
  92. if (bit != 0 && buffer.length() > 0)
  93. buffer.append(" | "); //$NON-NLS-1$
  94. switch (bit) {
  95. case IJavaSearchConstants.FIELD_DECLARATION_TYPE_REFERENCE:
  96. buffer.append("FIELD_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
  97. break;
  98. case IJavaSearchConstants.LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE:
  99. buffer.append("LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
  100. break;
  101. case IJavaSearchConstants.PARAMETER_DECLARATION_TYPE_REFERENCE:
  102. buffer.append("PARAMETER_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
  103. break;
  104. case IJavaSearchConstants.SUPERTYPE_TYPE_REFERENCE:
  105. buffer.append("SUPERTYPE_TYPE_REFERENCE"); //$NON-NLS-1$
  106. break;
  107. case IJavaSearchConstants.THROWS_CLAUSE_TYPE_REFERENCE:
  108. buffer.append("THROWS_CLAUSE_TYPE_REFERENCE"); //$NON-NLS-1$
  109. break;
  110. case IJavaSearchConstants.CAST_TYPE_REFERENCE:
  111. buffer.append("CAST_TYPE_REFERENCE"); //$NON-NLS-1$
  112. break;
  113. case IJavaSearchConstants.CATCH_TYPE_REFERENCE:
  114. buffer.append("CATCH_TYPE_REFERENCE"); //$NON-NLS-1$
  115. break;
  116. case IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE:
  117. buffer.append("CLASS_INSTANCE_CREATION_TYPE_REFERENCE"); //$NON-NLS-1$
  118. break;
  119. case IJavaSearchConstants.RETURN_TYPE_REFERENCE:
  120. buffer.append("RETURN_TYPE_REFERENCE"); //$NON-NLS-1$
  121. break;
  122. case IJavaSearchConstants.IMPORT_DECLARATION_TYPE_REFERENCE:
  123. buffer.append("IMPORT_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
  124. break;
  125. case IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE:
  126. buffer.append("ANNOTATION_TYPE_REFERENCE"); //$NON-NLS-1$
  127. break;
  128. case IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE:
  129. buffer.append("TYPE_ARGUMENT_TYPE_REFERENCE"); //$NON-NLS-1$
  130. break;
  131. case IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE:
  132. buffer.append("TYPE_VARIABLE_BOUND_TYPE_REFERENCE"); //$NON-NLS-1$
  133. break;
  134. case IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE:
  135. buffer.append("WILDCARD_BOUND_TYPE_REFERENCE"); //$NON-NLS-1$
  136. break;
  137. case IJavaSearchConstants.SUPER_REFERENCE:
  138. buffer.append("SUPER_REFERENCE"); //$NON-NLS-1$
  139. break;
  140. case IJavaSearchConstants.QUALIFIED_REFERENCE:
  141. buffer.append("QUALIFIED_REFERENCE"); //$NON-NLS-1$
  142. break;
  143. case IJavaSearchConstants.THIS_REFERENCE:
  144. buffer.append("THIS_REFERENCE"); //$NON-NLS-1$
  145. break;
  146. case IJavaSearchConstants.IMPLICIT_THIS_REFERENCE:
  147. buffer.append("IMPLICIT_THIS_REFERENCE"); //$NON-NLS-1$
  148. break;
  149. }
  150. }
  151. return buffer.toString();
  152. }
  153. public SearchPattern getBlankPattern() {
  154. return null;
  155. }
  156. final int getMatchMode() {
  157. return this.matchMode;
  158. }
  159. final boolean isCamelCase() {
  160. return this.isCamelCase;
  161. }
  162. final boolean isCaseSensitive() {
  163. return this.isCaseSensitive;
  164. }
  165. final boolean isErasureMatch() {
  166. return (this.matchCompatibility & R_ERASURE_MATCH) != 0;
  167. }
  168. final boolean isEquivalentMatch() {
  169. return (this.matchCompatibility & R_EQUIVALENT_MATCH) != 0;
  170. }
  171. /*
  172. * Extract method arguments using unique key for parameterized methods
  173. * and type parameters for non-generic ones.
  174. */
  175. char[][] extractMethodArguments(IMethod method) {
  176. // Use bind key if the element is resolved
  177. if (method.isResolved()) {
  178. BindingKey bindingKey= new BindingKey(method.getKey());
  179. if (bindingKey.isParameterizedMethod()) {
  180. String[] argumentsSignatures= bindingKey.getTypeArguments();
  181. int length= argumentsSignatures.length;
  182. if (length > 0) {
  183. char[][] methodArguments= new char[length][];
  184. for (int i= 0; i < length; i++) {
  185. methodArguments[i]= argumentsSignatures[i].toCharArray();
  186. CharOperation.replace(methodArguments[i], new char[] { '$', '/' }, '.');
  187. }
  188. return methodArguments;
  189. }
  190. }
  191. return null;
  192. }
  193. // Try to get the argument using the JavaModel info
  194. try {
  195. ITypeParameter[] parameters= method.getTypeParameters();
  196. if (parameters != null) {
  197. int length= parameters.length;
  198. if (length > 0) {
  199. char[][] arguments= new char[length][];
  200. for (int i= 0; i < length; i++) {
  201. arguments[i]= Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
  202. }
  203. return arguments;
  204. }
  205. }
  206. } catch (JavaModelException jme) {
  207. // do nothing
  208. }
  209. return null;
  210. }
  211. /**
  212. * @return Returns the typeArguments.
  213. */
  214. final char[][][] getTypeArguments() {
  215. return this.typeArguments;
  216. }
  217. /**
  218. * Returns whether the pattern has signatures or not. If pattern {@link #typeArguments} field,
  219. * this field shows that it was built on a generic source type.
  220. *
  221. * @return true if {@link #typeSignatures} field is not null and has a length greater than 0.
  222. */
  223. public final boolean hasSignatures() {
  224. return this.typeSignatures != null && this.typeSignatures.length > 0;
  225. }
  226. /**
  227. * Returns whether the pattern includes type arguments information or not.
  228. *
  229. * @return default is false
  230. */
  231. public final boolean hasTypeArguments() {
  232. return (this.flags & HAS_TYPE_ARGUMENTS) != 0;
  233. }
  234. /**
  235. * Returns whether the pattern includes type parameters information or not.
  236. *
  237. * @return true if {@link #typeArguments} contains type parameters instead type arguments
  238. * signatures.
  239. */
  240. public final boolean hasTypeParameters() {
  241. return !hasSignatures() && hasTypeArguments();
  242. }
  243. /**
  244. * Return whether two suffixes are compatible.
  245. *
  246. * Note that obvious compatibility values as equals and {@link IIndexConstants#TYPE_SUFFIX} has
  247. * to be tested by caller to avoid unnecessary method call...
  248. *
  249. * @param typeSuffix
  250. * @param patternSuffix
  251. * @return true if suffixes are compatible, false otherwise
  252. */
  253. boolean matchDifferentTypeSuffixes(int typeSuffix, int patternSuffix) {
  254. switch (typeSuffix) {
  255. case CLASS_SUFFIX:
  256. switch (patternSuffix) {
  257. case CLASS_AND_INTERFACE_SUFFIX:
  258. case CLASS_AND_ENUM_SUFFIX:
  259. return true;
  260. }
  261. return false;
  262. case INTERFACE_SUFFIX:
  263. switch (patternSuffix) {
  264. case CLASS_AND_INTERFACE_SUFFIX:
  265. case INTERFACE_AND_ANNOTATION_SUFFIX:
  266. return true;
  267. }
  268. return false;
  269. case ENUM_SUFFIX:
  270. return patternSuffix == CLASS_AND_ENUM_SUFFIX;
  271. case ANNOTATION_TYPE_SUFFIX:
  272. return patternSuffix == INTERFACE_AND_ANNOTATION_SUFFIX;
  273. case CLASS_AND_INTERFACE_SUFFIX:
  274. switch (patternSuffix) {
  275. case CLASS_SUFFIX:
  276. case INTERFACE_SUFFIX:
  277. return true;
  278. }
  279. return false;
  280. case CLASS_AND_ENUM_SUFFIX:
  281. switch (patternSuffix) {
  282. case CLASS_SUFFIX:
  283. case ENUM_SUFFIX:
  284. return true;
  285. }
  286. return false;
  287. case INTERFACE_AND_ANNOTATION_SUFFIX:
  288. switch (patternSuffix) {
  289. case INTERFACE_SUFFIX:
  290. case ANNOTATION_TYPE_SUFFIX:
  291. return true;
  292. }
  293. return false;
  294. }
  295. // Default behavior is to match suffixes
  296. return true;
  297. }
  298. protected StringBuffer print(StringBuffer output) {
  299. output.append(", "); //$NON-NLS-1$
  300. if (hasTypeArguments() && hasSignatures()) {
  301. output.append("signature:\""); //$NON-NLS-1$
  302. output.append(this.typeSignatures[0]);
  303. output.append("\", "); //$NON-NLS-1$
  304. }
  305. switch (getMatchMode()) {
  306. case R_EXACT_MATCH:
  307. output.append("exact match, "); //$NON-NLS-1$
  308. break;
  309. case R_PREFIX_MATCH:
  310. output.append("prefix match, "); //$NON-NLS-1$
  311. break;
  312. case R_PATTERN_MATCH:
  313. output.append("pattern match, "); //$NON-NLS-1$
  314. break;
  315. case R_REGEXP_MATCH:
  316. output.append("regexp match, "); //$NON-NLS-1$
  317. break;
  318. case R_CAMELCASE_MATCH:
  319. output.append("camel case match, "); //$NON-NLS-1$
  320. break;
  321. case R_CAMELCASE_SAME_PART_COUNT_MATCH:
  322. output.append("camel case same part count match, "); //$NON-NLS-1$
  323. break;
  324. }
  325. if (isCaseSensitive())
  326. output.append("case sensitive, "); //$NON-NLS-1$
  327. else
  328. output.append("case insensitive, "); //$NON-NLS-1$
  329. if ((this.matchCompatibility & R_FULL_MATCH) != 0) {
  330. output.append("generic full match, "); //$NON-NLS-1$
  331. }
  332. if ((this.matchCompatibility & R_ERASURE_MATCH) != 0) {
  333. output.append("generic erasure match, "); //$NON-NLS-1$
  334. }
  335. if ((this.matchCompatibility & R_EQUIVALENT_MATCH) != 0) {
  336. output.append("generic equivalent match, "); //$NON-NLS-1$
  337. }
  338. output.append("fine grain: "); //$NON-NLS-1$
  339. output.append(getFineGrainFlagString(this.fineGrain));
  340. return output;
  341. }
  342. /**
  343. * @param typeArguments The typeArguments to set.
  344. */
  345. final void setTypeArguments(char[][][] typeArguments) {
  346. this.typeArguments= typeArguments;
  347. // update flags
  348. if (this.typeArguments != null) {
  349. int length= this.typeArguments.length;
  350. for (int i= 0; i < length; i++) {
  351. if (this.typeArguments[i] != null && this.typeArguments[i].length > 0) {
  352. this.flags|= HAS_TYPE_ARGUMENTS;
  353. break;
  354. }
  355. }
  356. }
  357. }
  358. /*
  359. * Extract and store type signatures and arguments using unique key for parameterized types
  360. * and type parameters for non-generic ones
  361. */
  362. void storeTypeSignaturesAndArguments(IType type) {
  363. if (type.isResolved()) {
  364. BindingKey bindingKey= new BindingKey(type.getKey());
  365. if (bindingKey.isParameterizedType() || bindingKey.isRawType()) {
  366. String signature= bindingKey.toSignature();
  367. this.typeSignatures= Util.splitTypeLevelsSignature(signature);
  368. setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
  369. }
  370. return;
  371. }
  372. // Scan hierarchy to store type arguments at each level
  373. char[][][] typeParameters= new char[10][][];
  374. int ptr= -1;
  375. boolean hasParameters= false;
  376. try {
  377. IJavaElement parent= type;
  378. ITypeParameter[] parameters= null;
  379. while (parent != null && parent.getElementType() == IJavaElement.TYPE) {
  380. if (++ptr > typeParameters.length) {
  381. System.arraycopy(typeParameters, 0, typeParameters= new char[typeParameters.length + 10][][], 0, ptr);
  382. }
  383. IType parentType= (IType)parent;
  384. parameters= parentType.getTypeParameters();
  385. if (parameters != null) {
  386. int length= parameters.length;
  387. if (length > 0) {
  388. hasParameters= true;
  389. typeParameters[ptr]= new char[length][];
  390. for (int i= 0; i < length; i++)
  391. typeParameters[ptr][i]= Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
  392. }
  393. }
  394. parent= parent.getParent();
  395. }
  396. } catch (JavaModelException jme) {
  397. return;
  398. }
  399. // Store type arguments if any
  400. if (hasParameters) {
  401. if (++ptr < typeParameters.length)
  402. System.arraycopy(typeParameters, 0, typeParameters= new char[ptr][][], 0, ptr);
  403. setTypeArguments(typeParameters);
  404. }
  405. }
  406. public final String toString() {
  407. return print(new StringBuffer(30)).toString();
  408. }
  409. }