/plug-ins/helios/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
Java | 452 lines | 316 code | 43 blank | 93 comment | 61 complexity | 6e73cc3b4debf381f482a1ce6ab29c77 MD5 | raw file
- /*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
- package org.eclipse.jdt.internal.core.search.matching;
-
- import org.eclipse.jdt.core.BindingKey;
- import org.eclipse.jdt.core.IJavaElement;
- import org.eclipse.jdt.core.IMethod;
- import org.eclipse.jdt.core.IType;
- import org.eclipse.jdt.core.ITypeParameter;
- import org.eclipse.jdt.core.JavaModelException;
- import org.eclipse.jdt.core.Signature;
- import org.eclipse.jdt.core.compiler.CharOperation;
- import org.eclipse.jdt.core.search.IJavaSearchConstants;
- import org.eclipse.jdt.core.search.SearchPattern;
- import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
- import org.eclipse.jdt.internal.core.util.Util;
-
-
- public class JavaSearchPattern extends SearchPattern implements IIndexConstants {
-
- /*
- * Whether this pattern is case sensitive.
- */
- boolean isCaseSensitive;
-
- /*
- * Whether this pattern is camel case.
- */
- boolean isCamelCase;
-
- /**
- * One of following pattern value:
- * <ul>
- * <li>{@link #R_EXACT_MATCH}</li>
- * <li>{@link #R_PREFIX_MATCH}</li>
- * <li>{@link #R_PATTERN_MATCH}</li>
- * <li>{@link #R_REGEXP_MATCH}</li>
- * <li>{@link #R_CAMELCASE_MATCH}</li>
- * <li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}</li>
- * </ul>
- */
- int matchMode;
-
- /**
- * One of {@link #R_ERASURE_MATCH}, {@link #R_EQUIVALENT_MATCH}, {@link #R_FULL_MATCH}.
- */
- int matchCompatibility;
-
- /**
- * Fine grain limitation
- */
- public int fineGrain= 0;
-
- /**
- * Mask used on match rule for match mode.
- */
- public static final int MATCH_MODE_MASK= R_EXACT_MATCH
- | R_PREFIX_MATCH
- | R_PATTERN_MATCH
- | R_REGEXP_MATCH
- | R_CAMELCASE_MATCH
- | R_CAMELCASE_SAME_PART_COUNT_MATCH;
-
- /**
- * Mask used on match rule for generic relevance.
- */
- public static final int MATCH_COMPATIBILITY_MASK= R_ERASURE_MATCH | R_EQUIVALENT_MATCH | R_FULL_MATCH;
-
- // Signatures and arguments for parameterized types search
- char[][] typeSignatures;
-
- private char[][][] typeArguments;
-
- private int flags= 0;
-
- static final int HAS_TYPE_ARGUMENTS= 1;
-
- protected JavaSearchPattern(int patternKind, int matchRule) {
- super(matchRule);
- this.kind= patternKind;
- // Use getMatchRule() instead of matchRule as super constructor may modify its value
- // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=81377
- int rule= getMatchRule();
- this.isCaseSensitive= (rule & R_CASE_SENSITIVE) != 0;
- this.isCamelCase= (rule & (R_CAMELCASE_MATCH | R_CAMELCASE_SAME_PART_COUNT_MATCH)) != 0;
- this.matchCompatibility= rule & MATCH_COMPATIBILITY_MASK;
- this.matchMode= rule & MATCH_MODE_MASK;
- }
-
- /**
- * @param fineGrain
- */
- public static String getFineGrainFlagString(final int fineGrain) {
- if (fineGrain == 0) {
- return "none"; //$NON-NLS-1$
- }
- StringBuffer buffer= new StringBuffer();
- for (int i= 1; i <= 32; i++) {
- int bit= fineGrain & (1 << (i - 1));
- if (bit != 0 && buffer.length() > 0)
- buffer.append(" | "); //$NON-NLS-1$
- switch (bit) {
- case IJavaSearchConstants.FIELD_DECLARATION_TYPE_REFERENCE:
- buffer.append("FIELD_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE:
- buffer.append("LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.PARAMETER_DECLARATION_TYPE_REFERENCE:
- buffer.append("PARAMETER_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.SUPERTYPE_TYPE_REFERENCE:
- buffer.append("SUPERTYPE_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.THROWS_CLAUSE_TYPE_REFERENCE:
- buffer.append("THROWS_CLAUSE_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.CAST_TYPE_REFERENCE:
- buffer.append("CAST_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.CATCH_TYPE_REFERENCE:
- buffer.append("CATCH_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE:
- buffer.append("CLASS_INSTANCE_CREATION_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.RETURN_TYPE_REFERENCE:
- buffer.append("RETURN_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.IMPORT_DECLARATION_TYPE_REFERENCE:
- buffer.append("IMPORT_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE:
- buffer.append("ANNOTATION_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE:
- buffer.append("TYPE_ARGUMENT_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE:
- buffer.append("TYPE_VARIABLE_BOUND_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE:
- buffer.append("WILDCARD_BOUND_TYPE_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.SUPER_REFERENCE:
- buffer.append("SUPER_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.QUALIFIED_REFERENCE:
- buffer.append("QUALIFIED_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.THIS_REFERENCE:
- buffer.append("THIS_REFERENCE"); //$NON-NLS-1$
- break;
- case IJavaSearchConstants.IMPLICIT_THIS_REFERENCE:
- buffer.append("IMPLICIT_THIS_REFERENCE"); //$NON-NLS-1$
- break;
- }
- }
- return buffer.toString();
- }
-
- public SearchPattern getBlankPattern() {
- return null;
- }
-
- final int getMatchMode() {
- return this.matchMode;
- }
-
- final boolean isCamelCase() {
- return this.isCamelCase;
- }
-
- final boolean isCaseSensitive() {
- return this.isCaseSensitive;
- }
-
- final boolean isErasureMatch() {
- return (this.matchCompatibility & R_ERASURE_MATCH) != 0;
- }
-
- final boolean isEquivalentMatch() {
- return (this.matchCompatibility & R_EQUIVALENT_MATCH) != 0;
- }
-
- /*
- * Extract method arguments using unique key for parameterized methods
- * and type parameters for non-generic ones.
- */
- char[][] extractMethodArguments(IMethod method) {
-
- // Use bind key if the element is resolved
- if (method.isResolved()) {
- BindingKey bindingKey= new BindingKey(method.getKey());
- if (bindingKey.isParameterizedMethod()) {
- String[] argumentsSignatures= bindingKey.getTypeArguments();
- int length= argumentsSignatures.length;
- if (length > 0) {
- char[][] methodArguments= new char[length][];
- for (int i= 0; i < length; i++) {
- methodArguments[i]= argumentsSignatures[i].toCharArray();
- CharOperation.replace(methodArguments[i], new char[] { '$', '/' }, '.');
- }
- return methodArguments;
- }
- }
- return null;
- }
-
- // Try to get the argument using the JavaModel info
- try {
- ITypeParameter[] parameters= method.getTypeParameters();
- if (parameters != null) {
- int length= parameters.length;
- if (length > 0) {
- char[][] arguments= new char[length][];
- for (int i= 0; i < length; i++) {
- arguments[i]= Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
- }
- return arguments;
- }
- }
- } catch (JavaModelException jme) {
- // do nothing
- }
- return null;
- }
-
- /**
- * @return Returns the typeArguments.
- */
- final char[][][] getTypeArguments() {
- return this.typeArguments;
- }
-
- /**
- * Returns whether the pattern has signatures or not. If pattern {@link #typeArguments} field,
- * this field shows that it was built on a generic source type.
- *
- * @return true if {@link #typeSignatures} field is not null and has a length greater than 0.
- */
- public final boolean hasSignatures() {
- return this.typeSignatures != null && this.typeSignatures.length > 0;
- }
-
- /**
- * Returns whether the pattern includes type arguments information or not.
- *
- * @return default is false
- */
- public final boolean hasTypeArguments() {
- return (this.flags & HAS_TYPE_ARGUMENTS) != 0;
- }
-
- /**
- * Returns whether the pattern includes type parameters information or not.
- *
- * @return true if {@link #typeArguments} contains type parameters instead type arguments
- * signatures.
- */
- public final boolean hasTypeParameters() {
- return !hasSignatures() && hasTypeArguments();
- }
-
- /**
- * Return whether two suffixes are compatible.
- *
- * Note that obvious compatibility values as equals and {@link IIndexConstants#TYPE_SUFFIX} has
- * to be tested by caller to avoid unnecessary method call...
- *
- * @param typeSuffix
- * @param patternSuffix
- * @return true if suffixes are compatible, false otherwise
- */
- boolean matchDifferentTypeSuffixes(int typeSuffix, int patternSuffix) {
- switch (typeSuffix) {
- case CLASS_SUFFIX:
- switch (patternSuffix) {
- case CLASS_AND_INTERFACE_SUFFIX:
- case CLASS_AND_ENUM_SUFFIX:
- return true;
- }
- return false;
-
- case INTERFACE_SUFFIX:
- switch (patternSuffix) {
- case CLASS_AND_INTERFACE_SUFFIX:
- case INTERFACE_AND_ANNOTATION_SUFFIX:
- return true;
- }
- return false;
-
- case ENUM_SUFFIX:
- return patternSuffix == CLASS_AND_ENUM_SUFFIX;
-
- case ANNOTATION_TYPE_SUFFIX:
- return patternSuffix == INTERFACE_AND_ANNOTATION_SUFFIX;
-
- case CLASS_AND_INTERFACE_SUFFIX:
- switch (patternSuffix) {
- case CLASS_SUFFIX:
- case INTERFACE_SUFFIX:
- return true;
- }
- return false;
-
- case CLASS_AND_ENUM_SUFFIX:
- switch (patternSuffix) {
- case CLASS_SUFFIX:
- case ENUM_SUFFIX:
- return true;
- }
- return false;
-
- case INTERFACE_AND_ANNOTATION_SUFFIX:
- switch (patternSuffix) {
- case INTERFACE_SUFFIX:
- case ANNOTATION_TYPE_SUFFIX:
- return true;
- }
- return false;
- }
-
- // Default behavior is to match suffixes
- return true;
- }
-
- protected StringBuffer print(StringBuffer output) {
- output.append(", "); //$NON-NLS-1$
- if (hasTypeArguments() && hasSignatures()) {
- output.append("signature:\""); //$NON-NLS-1$
- output.append(this.typeSignatures[0]);
- output.append("\", "); //$NON-NLS-1$
- }
- switch (getMatchMode()) {
- case R_EXACT_MATCH:
- output.append("exact match, "); //$NON-NLS-1$
- break;
- case R_PREFIX_MATCH:
- output.append("prefix match, "); //$NON-NLS-1$
- break;
- case R_PATTERN_MATCH:
- output.append("pattern match, "); //$NON-NLS-1$
- break;
- case R_REGEXP_MATCH:
- output.append("regexp match, "); //$NON-NLS-1$
- break;
- case R_CAMELCASE_MATCH:
- output.append("camel case match, "); //$NON-NLS-1$
- break;
- case R_CAMELCASE_SAME_PART_COUNT_MATCH:
- output.append("camel case same part count match, "); //$NON-NLS-1$
- break;
- }
- if (isCaseSensitive())
- output.append("case sensitive, "); //$NON-NLS-1$
- else
- output.append("case insensitive, "); //$NON-NLS-1$
- if ((this.matchCompatibility & R_FULL_MATCH) != 0) {
- output.append("generic full match, "); //$NON-NLS-1$
- }
- if ((this.matchCompatibility & R_ERASURE_MATCH) != 0) {
- output.append("generic erasure match, "); //$NON-NLS-1$
- }
- if ((this.matchCompatibility & R_EQUIVALENT_MATCH) != 0) {
- output.append("generic equivalent match, "); //$NON-NLS-1$
- }
- output.append("fine grain: "); //$NON-NLS-1$
- output.append(getFineGrainFlagString(this.fineGrain));
- return output;
- }
-
- /**
- * @param typeArguments The typeArguments to set.
- */
- final void setTypeArguments(char[][][] typeArguments) {
- this.typeArguments= typeArguments;
- // update flags
- if (this.typeArguments != null) {
- int length= this.typeArguments.length;
- for (int i= 0; i < length; i++) {
- if (this.typeArguments[i] != null && this.typeArguments[i].length > 0) {
- this.flags|= HAS_TYPE_ARGUMENTS;
- break;
- }
- }
- }
- }
-
- /*
- * Extract and store type signatures and arguments using unique key for parameterized types
- * and type parameters for non-generic ones
- */
- void storeTypeSignaturesAndArguments(IType type) {
- if (type.isResolved()) {
- BindingKey bindingKey= new BindingKey(type.getKey());
- if (bindingKey.isParameterizedType() || bindingKey.isRawType()) {
- String signature= bindingKey.toSignature();
- this.typeSignatures= Util.splitTypeLevelsSignature(signature);
- setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
- }
- return;
- }
-
- // Scan hierarchy to store type arguments at each level
- char[][][] typeParameters= new char[10][][];
- int ptr= -1;
- boolean hasParameters= false;
- try {
- IJavaElement parent= type;
- ITypeParameter[] parameters= null;
- while (parent != null && parent.getElementType() == IJavaElement.TYPE) {
- if (++ptr > typeParameters.length) {
- System.arraycopy(typeParameters, 0, typeParameters= new char[typeParameters.length + 10][][], 0, ptr);
- }
- IType parentType= (IType)parent;
- parameters= parentType.getTypeParameters();
- if (parameters != null) {
- int length= parameters.length;
- if (length > 0) {
- hasParameters= true;
- typeParameters[ptr]= new char[length][];
- for (int i= 0; i < length; i++)
- typeParameters[ptr][i]= Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
- }
- }
- parent= parent.getParent();
- }
- } catch (JavaModelException jme) {
- return;
- }
-
- // Store type arguments if any
- if (hasParameters) {
- if (++ptr < typeParameters.length)
- System.arraycopy(typeParameters, 0, typeParameters= new char[ptr][][], 0, ptr);
- setTypeArguments(typeParameters);
- }
- }
-
- public final String toString() {
- return print(new StringBuffer(30)).toString();
- }
- }