Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/FieldPattern.java')
-rw-r--r--bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/FieldPattern.java577
1 files changed, 458 insertions, 119 deletions
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/FieldPattern.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/FieldPattern.java
index 95fc070c..84334827 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/FieldPattern.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/FieldPattern.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -10,138 +10,477 @@
*******************************************************************************/
package org.eclipse.wst.jsdt.internal.core.search.matching;
+import java.io.IOException;
+
import org.eclipse.wst.jsdt.core.IField;
import org.eclipse.wst.jsdt.core.compiler.CharOperation;
import org.eclipse.wst.jsdt.core.search.SearchPattern;
-import org.eclipse.wst.jsdt.internal.core.util.Util;
+import org.eclipse.wst.jsdt.internal.core.Logger;
+import org.eclipse.wst.jsdt.internal.core.index.EntryResult;
+import org.eclipse.wst.jsdt.internal.core.index.Index;
+import org.eclipse.wst.jsdt.internal.core.util.QualificationHelpers;
public class FieldPattern extends VariablePattern {
+ /**
+ * <p><b>Optional</b></p>
+ *
+ * <p>Qualification of the declaring type containing this field.</p>
+ *
+ * <p>This can either be a single qualification if this pattern is representing a specific field
+ * defined on a specific type, or it can be a list of qualifications if it is a pattern for finding
+ * a field that could be defined on many different types.</p>
+ *
+ * <p><b>Note:</b> If this field is defined then the {@link #declaringSimpleName} must
+ * also be defined.</p>
+ *
+ * @see #declaringSimpleName
+ */
+ private char[][] declaringQualification;
+
+ /**
+ * <p><b>Optional</b></p>
+ *
+ * <p>Simple name of the declaring type containing this field.</p>
+ *
+ * <p>This can either be a single simple name if this pattern is representing a specific field
+ * defined on a specific type, or it can be a list of simple names if it is a pattern for finding
+ * a field that could be defined on many different types.</p>
+ *
+ * <p><b>Note:</b> If this field is defined then the {@link #declaringQualification}
+ * can be defined, but does not have to be.</p>
+ *
+ * @see #declaringQualification
+ */
+ private char[][] declaringSimpleName;
+
+ // type
+ public char[] typeQualification;
+ public char[] typeSimpleName;
+
+ // modifiers
+ public int modifiers;
+
+ protected static char[][] REF_CATEGORIES = { REF };
+ protected static char[][] REF_AND_DECL_CATEGORIES = { REF, FIELD_DECL, VAR_DECL };
+ protected static char[][] DECL_CATEGORIES = { FIELD_DECL, VAR_DECL };
+
+ /**
+ * @deprecated this will be removed at some point
+ */
+ protected boolean isVar;
+
+ /**
+ * <p>Creates a field pattern index key based on the given information.</p>
+ *
+ * @param fieldName
+ * @param typeName
+ * @param declaringType
+ * @param modifiers
+ * @return
+ */
+ public static char[] createIndexKey(char[] fieldName, char[] typeName, char[] declaringType, int modifiers) {
+ char[] indexKey = null;
+
+ if(fieldName != null && fieldName.length > 0) {
+ //get lengths
+ int typeNameLength= (typeName == null ? 0 : typeName.length);
+ int declaringTypeLength = (declaringType == null ? 0 : declaringType.length);
+
+ int resultLength = fieldName.length
+ + 1 + typeNameLength
+ + 1 + declaringTypeLength
+ + 3; //modifiers
+
+ //create result char array
+ indexKey = new char[resultLength];
+
+ //add type name to result
+ int pos = 0;
+ System.arraycopy(fieldName, 0, indexKey, pos, fieldName.length);
+ pos += fieldName.length;
+
+ //add declaring type
+ indexKey[pos++] = SEPARATOR;
+ if(declaringTypeLength > 0) {
+ System.arraycopy(declaringType, 0, indexKey, pos, declaringTypeLength);
+ pos += declaringTypeLength;
+ }
+
+ //add type
+ indexKey[pos++] = SEPARATOR;
+ if(typeNameLength > 0) {
+ System.arraycopy(typeName, 0, indexKey, pos, typeNameLength);
+ pos += typeNameLength;
+ }
+
+ //add modifiers
+ indexKey[pos++] = SEPARATOR;
+ indexKey[pos++] = (char) modifiers;
+ indexKey[pos++] = (char) (modifiers>>16);
+ }
+
+ return indexKey;
+ }
+
+ /**
+ * <p>Constructor good for creating a pattern to find a field that could be defined
+ * on one of many different specified types.</p>
+ *
+ * @param findDeclarations
+ * @param readAccess
+ * @param writeAccess
+ * @param isVar
+ * @param name
+ * @param possibleDeclaringTypes optional list of possible declaring types that the given selector must be
+ * defined on one of to be a valid match, or <code>null</code> to specify the field is not
+ * defined on a type
+ * @param typeQualification
+ * @param typeSimpleName
+ * @param matchRule
+ * @param field
+ */
+ public FieldPattern(
+ boolean findDeclarations,
+ boolean readAccess,
+ boolean writeAccess,
+ boolean isVar,
+ char[] name,
+ char[][] possibleDeclaringTypes,
+ char[] typeQualification,
+ char[] typeSimpleName,
+ int matchRule, IField field) {
+
+ super(FIELD_PATTERN, findDeclarations, readAccess, writeAccess, name, matchRule,field);
+
+ this.isVar=isVar;
+ if(possibleDeclaringTypes != null) {
+ this.declaringQualification = new char[possibleDeclaringTypes.length][];
+ this.declaringSimpleName = new char[possibleDeclaringTypes.length][];
+ for(int i = 0; i < possibleDeclaringTypes.length; i++) {
+ char[][] seperatedDeclaringType = QualificationHelpers.seperateFullyQualifedName(possibleDeclaringTypes[i]);
+ this.declaringQualification[i] = isCaseSensitive() ?
+ seperatedDeclaringType[QualificationHelpers.QULIFIERS_INDEX] : CharOperation.toLowerCase(seperatedDeclaringType[QualificationHelpers.QULIFIERS_INDEX]);
+ this.declaringSimpleName[i] = isCaseSensitive() ?
+ seperatedDeclaringType[QualificationHelpers.SIMPLE_NAMES_INDEX] : CharOperation.toLowerCase(seperatedDeclaringType[QualificationHelpers.SIMPLE_NAMES_INDEX]);
+ }
+ }
+ this.typeQualification = isCaseSensitive() ? typeQualification : CharOperation.toLowerCase(typeQualification);
+ this.typeSimpleName = (isCaseSensitive() || isCamelCase()) ? typeSimpleName : CharOperation.toLowerCase(typeSimpleName);
+
+ ((InternalSearchPattern)this).mustResolve = mustResolve();
+ }
+
+ /**
+ *
+ * <p>Constructor useful for searching for a specific field on a specific type.</p>
+ *
+ * @param findDeclarations
+ * @param readAccess
+ * @param writeAccess
+ * @param name
+ * @param declaringQualification
+ * @param declaringSimpleName
+ * @param matchRule
+ */
+ public FieldPattern(
+ boolean findDeclarations,
+ boolean readAccess,
+ boolean writeAccess,
+ char[] name,
+ char[] declaringQualification,
+ char[] declaringSimpleName,
+ int matchRule) {
+
+ this(findDeclarations, readAccess, writeAccess, false,
+ name, declaringQualification, declaringSimpleName, null, null, matchRule, null);
+ }
+
+ /**
+ * <p>Constructor useful for searching for a specific field on a specific type.</p>
+ *
+ * @param findDeclarations
+ * @param readAccess
+ * @param writeAccess
+ * @param isVar
+ * @param name
+ * @param declaringQualification
+ * @param declaringSimpleName
+ * @param typeQualification
+ * @param typeSimpleName
+ * @param matchRule
+ * @param field
+ */
+ public FieldPattern(
+ boolean findDeclarations,
+ boolean readAccess,
+ boolean writeAccess,
+ boolean isVar,
+ char[] name,
+ char[] declaringQualification,
+ char[] declaringSimpleName,
+ char[] typeQualification,
+ char[] typeSimpleName,
+ int matchRule, IField field) {
+
+ super(FIELD_PATTERN, findDeclarations, readAccess, writeAccess, name, matchRule,field);
+
+ this.isVar=isVar;
+
+ this.setDeclaringQualification(declaringQualification);
+ this.setDeclaringSimpleName(declaringSimpleName);
+ this.typeQualification = isCaseSensitive() ? typeQualification : CharOperation.toLowerCase(typeQualification);
+ this.typeSimpleName = (isCaseSensitive() || isCamelCase()) ? typeSimpleName : CharOperation.toLowerCase(typeSimpleName);
+
+ ((InternalSearchPattern)this).mustResolve = mustResolve();
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.core.search.SearchPattern#decodeIndexKey(char[])
+ */
+ public void decodeIndexKey(char[] key) {
+ char[][] seperated = CharOperation.splitOn(SEPARATOR, key);
+
+ //get the name
+ this.name = seperated[0];
+
+ if (seperated.length > 1) {
+ // get the declaring type
+ char[][] declaringType = QualificationHelpers.seperateFullyQualifedName(seperated[1]);
+ this.setDeclaringQualification(declaringType[QualificationHelpers.QULIFIERS_INDEX]);
+ this.setDeclaringSimpleName(declaringType[QualificationHelpers.SIMPLE_NAMES_INDEX]);
-// declaring type
-protected char[] declaringQualification;
-protected char[] declaringSimpleName;
-
-// type
-protected char[] typeQualification;
-protected char[] typeSimpleName;
-
-protected static char[][] REF_CATEGORIES = { REF };
-protected static char[][] REF_AND_DECL_CATEGORIES = { REF, FIELD_DECL };
-protected static char[][] DECL_CATEGORIES = { FIELD_DECL };
-protected static char[][] VAR_REF_AND_DECL_CATEGORIES = { REF, VAR_DECL };
-protected static char[][] VAR_DECL_CATEGORIES = { VAR_DECL };
-protected boolean isVar;
-
-public static char[] createIndexKey(char[] fieldName) {
- return fieldName;
-}
-
-public FieldPattern(
- boolean findDeclarations,
- boolean readAccess,
- boolean writeAccess,
- boolean isVar,
- char[] name,
- char[] declaringQualification,
- char[] declaringSimpleName,
- char[] typeQualification,
- char[] typeSimpleName,
- int matchRule, IField field) {
-
- super(FIELD_PATTERN, findDeclarations, readAccess, writeAccess, name, matchRule,field);
-
- this.isVar=isVar;
- this.declaringQualification = isCaseSensitive() ? declaringQualification : CharOperation.toLowerCase(declaringQualification);
- this.declaringSimpleName = isCaseSensitive() ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
- this.typeQualification = isCaseSensitive() ? typeQualification : CharOperation.toLowerCase(typeQualification);
- this.typeSimpleName = (isCaseSensitive() || isCamelCase()) ? typeSimpleName : CharOperation.toLowerCase(typeSimpleName);
-
- ((InternalSearchPattern)this).mustResolve = mustResolve();
-}
-/*
- * Instanciate a field pattern with additional information for generics search
- */
-public FieldPattern(
- boolean findDeclarations,
- boolean readAccess,
- boolean writeAccess,
- boolean isVar,
- char[] name,
- char[] declaringQualification,
- char[] declaringSimpleName,
- char[] typeQualification,
- char[] typeSimpleName,
- String typeSignature,
- int matchRule, IField field) {
-
- this(findDeclarations, readAccess, writeAccess, isVar, name, declaringQualification, declaringSimpleName, typeQualification, typeSimpleName, matchRule,field);
+ // get the type of the field
+ char[][] type = QualificationHelpers.seperateFullyQualifedName(seperated[2]);
+ this.typeQualification = type[QualificationHelpers.QULIFIERS_INDEX];
+ this.typeSimpleName = type[QualificationHelpers.SIMPLE_NAMES_INDEX];
- // store type signatures and arguments
- if (typeSignature != null) {
- this.typeSignatures = Util.splitTypeLevelsSignature(typeSignature);
- setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+ // get the modifiers
+ this.modifiers = seperated[3][0] + seperated[3][1];
+ }
}
-}
-public void decodeIndexKey(char[] key) {
- this.name = key;
-}
-public SearchPattern getBlankPattern() {
- return new FieldPattern(false, false, false, isVar, null, null, null, null, null, R_EXACT_MATCH | R_CASE_SENSITIVE,null);
-}
-public char[] getIndexKey() {
- return this.name;
-}
-public char[][] getIndexCategories() {
+
+ /**
+ * @see org.eclipse.wst.jsdt.internal.core.search.matching.JavaSearchPattern#getBlankPattern()
+ */
+ public SearchPattern getBlankPattern() {
+ return new FieldPattern(false, false, false, isVar, null, null, null, null, R_EXACT_MATCH | R_CASE_SENSITIVE,null);
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.core.search.SearchPattern#getIndexKey()
+ */
+ public char[] getIndexKey() {
+ return this.name;
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.internal.core.search.matching.InternalSearchPattern#queryIn(org.eclipse.wst.jsdt.internal.core.index.Index)
+ */
+ EntryResult[] queryIn(Index index) throws IOException {
+ //might have to do multiple searches
+ EntryResult[] results = null;
+ char[][] keys = null;
+ int[] matchRules = null;
+
+ if (this.findReferences && (this.findDeclarations || this.writeAccess)) {
+ keys = new char[2][];
+ matchRules = new int[2];
+ } else {
+ keys = new char[1][];
+ matchRules = new int[1];
+ }
+
+ keys[0] = this.name; // can be null
+ matchRules[0] = getMatchRule();
+
+ if (this.findDeclarations || this.writeAccess) {
+ switch (getMatchMode()) {
+ case R_EXACT_MATCH :
+ // can not do an exact match with camel case
+ if (this.isCamelCase)
+ break;
- if (this.isVar) {
- if (this.findReferences)
- return this.findDeclarations || this.writeAccess ? VAR_REF_AND_DECL_CATEGORIES
- : REF_CATEGORIES;
- if (this.findDeclarations)
- return VAR_DECL_CATEGORIES;
+ /*
+ * do a prefix match on name/declaringType/
+ */
+ keys[0] = CharOperation.concat(this.name, QualificationHelpers.createFullyQualifiedName(this.getDeclaringQualification(), this.getDeclaringSimpleName()), SEPARATOR);
+ keys[0] = CharOperation.append(keys[0], SEPARATOR);
+ matchRules[0] &= ~R_EXACT_MATCH;
+ matchRules[0] |= R_PREFIX_MATCH;
+ break;
+ case R_PREFIX_MATCH :
+ break;
+ case R_PATTERN_MATCH :
+ keys[0] = createSearchIndexKey(this.name, this.getDeclaringQualification(), this.getDeclaringSimpleName());
+ break;
+ case R_REGEXP_MATCH :
+ Logger.log(Logger.WARNING, "Regular expression matching is not yet implimented for MethodPattern");
+ break;
+ }
+ }
+
+ if (this.findReferences && (this.findDeclarations || this.writeAccess)) {
+ keys[1] = this.name; // can be null
+ matchRules[1] = getMatchRule();
+ }
+
+ //run a search for each search key
+ for (int i = 0; i < keys.length; ++i) {
+ //run search
+ EntryResult[] additionalResults = index.query(getIndexCategories(), keys[i], matchRules[i]);
+
+ //collect results
+ if (additionalResults != null && additionalResults.length > 0) {
+ if (results == null) {
+ results = additionalResults;
+ } else {
+ EntryResult[] existingResults = results;
+
+ results = new EntryResult[existingResults.length + additionalResults.length];
+
+ System.arraycopy(existingResults, 0, results, 0, existingResults.length);
+ System.arraycopy(additionalResults, 0, results, existingResults.length, additionalResults.length);
+ }
+ }
+ }
+ return results;
}
- else {
+ public char[][] getIndexCategories() {
if (this.findReferences)
return this.findDeclarations || this.writeAccess ? REF_AND_DECL_CATEGORIES
: REF_CATEGORIES;
if (this.findDeclarations)
return DECL_CATEGORIES;
-
+
+ return CharOperation.NO_CHAR_CHAR;
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.core.search.SearchPattern#matchesDecodedKey(org.eclipse.wst.jsdt.core.search.SearchPattern)
+ */
+ public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+ boolean matches = false;
+ if(decodedPattern instanceof FieldPattern) {
+ FieldPattern pattern = (FieldPattern) decodedPattern;
+
+ matches = matchesName(this.name, pattern.name);
+
+ if(matches && this.declaringSimpleName != null) {
+ boolean foundTypeMatch = false;
+ for(int i = 0; i < this.declaringSimpleName.length; i++) {
+ if(matchesName(this.declaringQualification[i], pattern.getDeclaringQualification())
+ && matchesName(this.declaringSimpleName[i], pattern.getDeclaringSimpleName())) {
+ foundTypeMatch = true;
+ break;
+ }
+ }
+ if(!foundTypeMatch)
+ matches = false;
+ }
+ }
+
+ return matches;
+ }
+
+ /**
+ * @return the declaring qualification for this pattern, or <code>null</code> if no declaring qualification
+ */
+ public char[] getDeclaringQualification() {
+ return this.declaringQualification != null && this.declaringQualification.length > 0 ?
+ this.declaringQualification[0] : null;
+ }
+
+ /**
+ * @return the declaring simple name for this pattern, or <code>null</code> if no declaring simple name
+ */
+ public char[] getDeclaringSimpleName() {
+ return this.declaringSimpleName != null && this.declaringSimpleName.length > 0 ?
+ this.declaringSimpleName[0] : null;
+ }
+
+ /**
+ * <p>Sets the declaring qualification for this pattern.</p>
+ * <p>If the declaring qualification is set then the declaring simple name must also be set.</p>
+ *
+ * @param declaringQualification declaring qualification for this pattern
+ *
+ * @see #setDeclaringSimpleName(char[])
+ */
+ private void setDeclaringQualification(char[] declaringQualification) {
+ this.declaringQualification = new char[1][];
+ this.declaringQualification[0] = declaringQualification;
+ }
+
+ /**
+ * <p>Sets the declaring simple name for this pattern</p>
+ *
+ * @param declaringSimpleName declaring simple name for this pattern
+ */
+ private void setDeclaringSimpleName(char[] declaringSimpleName) {
+ this.declaringSimpleName = new char[1][];
+ this.declaringSimpleName[0] = declaringSimpleName;
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.internal.core.search.matching.VariablePattern#mustResolve()
+ */
+ protected boolean mustResolve() {
+ if (!isVar && this.findDeclarations)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.internal.core.search.matching.JavaSearchPattern#print(java.lang.StringBuffer)
+ */
+ protected StringBuffer print(StringBuffer output) {
+ if (this.findDeclarations) {
+ output.append(this.findReferences
+ ? "FieldCombinedPattern: " //$NON-NLS-1$
+ : "FieldDeclarationPattern: "); //$NON-NLS-1$
+ } else {
+ output.append("FieldReferencePattern: "); //$NON-NLS-1$
+ }
+ if (this.getDeclaringQualification() != null) output.append(this.getDeclaringQualification()).append('.');
+ if (this.getDeclaringSimpleName() != null)
+ output.append(this.getDeclaringSimpleName()).append('.');
+ else if (this.getDeclaringSimpleName() != null) output.append("*."); //$NON-NLS-1$
+ if (name == null) {
+ output.append("*"); //$NON-NLS-1$
+ } else {
+ output.append(name);
+ }
+ if (typeQualification != null)
+ output.append(" --> ").append(typeQualification).append('.'); //$NON-NLS-1$
+ else if (typeSimpleName != null) output.append(" --> "); //$NON-NLS-1$
+ if (typeSimpleName != null)
+ output.append(typeSimpleName);
+ else if (typeQualification != null) output.append("*"); //$NON-NLS-1$
+ return super.print(output);
+ }
+
+ /**
+ * <p>Create an index key for search the index for any field that matches the given selector,
+ * on the optionally defined declaring type.</p>
+ *
+ * @param name
+ * @param declaringQualification
+ * @param declaringSimpleName
+ *
+ * @return
+ */
+ private static char[] createSearchIndexKey(char[] name,
+ char[] declaringQualification, char[] declaringSimpleName) {
+
+ char[] declaringFullTypeName = null;
+ if(declaringSimpleName != null) {
+ declaringFullTypeName = QualificationHelpers.createFullyQualifiedName(declaringQualification, declaringSimpleName);
+ }
+
+ return createIndexKey(name,
+ ONE_STAR,
+ declaringFullTypeName != null ? declaringFullTypeName : ONE_STAR,
+ 0);
}
- return CharOperation.NO_CHAR_CHAR;
-}
-public boolean matchesDecodedKey(SearchPattern decodedPattern) {
- return true; // index key is not encoded so query results all match
-}
-protected boolean mustResolve() {
- if (this.declaringSimpleName != null || this.declaringQualification != null) return true;
- if (this.typeSimpleName != null || this.typeQualification != null) return true;
-
- return super.mustResolve();
-}
-protected StringBuffer print(StringBuffer output) {
- if (this.findDeclarations) {
- output.append(this.findReferences
- ? "FieldCombinedPattern: " //$NON-NLS-1$
- : "FieldDeclarationPattern: "); //$NON-NLS-1$
- } else {
- output.append("FieldReferencePattern: "); //$NON-NLS-1$
- }
- if (declaringQualification != null) output.append(declaringQualification).append('.');
- if (declaringSimpleName != null)
- output.append(declaringSimpleName).append('.');
- else if (declaringQualification != null) output.append("*."); //$NON-NLS-1$
- if (name == null) {
- output.append("*"); //$NON-NLS-1$
- } else {
- output.append(name);
- }
- if (typeQualification != null)
- output.append(" --> ").append(typeQualification).append('.'); //$NON-NLS-1$
- else if (typeSimpleName != null) output.append(" --> "); //$NON-NLS-1$
- if (typeSimpleName != null)
- output.append(typeSimpleName);
- else if (typeQualification != null) output.append("*"); //$NON-NLS-1$
- return super.print(output);
-}
}

Back to the top