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/TypeDeclarationPattern.java')
-rw-r--r--bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/TypeDeclarationPattern.java842
1 files changed, 516 insertions, 326 deletions
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/TypeDeclarationPattern.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/TypeDeclarationPattern.java
index bbb9fe35..5a357d59 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/TypeDeclarationPattern.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/matching/TypeDeclarationPattern.java
@@ -1,326 +1,516 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2010 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
- * Michael Spector <spektom@gmail.com> Bug 242987
- *******************************************************************************/
-package org.eclipse.wst.jsdt.internal.core.search.matching;
-
-import java.io.IOException;
-
-import org.eclipse.wst.jsdt.core.compiler.CharOperation;
-import org.eclipse.wst.jsdt.core.search.SearchPattern;
-import org.eclipse.wst.jsdt.internal.core.index.EntryResult;
-import org.eclipse.wst.jsdt.internal.core.index.Index;
-
-public class TypeDeclarationPattern extends JavaSearchPattern {
-
-public char[] simpleName;
-public char[] pkg;
-public char[][] enclosingTypeNames;
-
-// set to CLASS_SUFFIX for only matching classes
-// set to INTERFACE_SUFFIX for only matching interfaces
-// set to ENUM_SUFFIX for only matching enums
-// set to ANNOTATION_TYPE_SUFFIX for only matching annotation types
-// set to TYPE_SUFFIX for matching both classes and interfaces
-public char typeSuffix;
-public int modifiers;
-public boolean secondary = false;
-
-protected static char[][] CATEGORIES = { TYPE_DECL };
-
-// want to save space by interning the package names for each match
-static PackageNameSet internedPackageNames = new PackageNameSet(1001);
-static class PackageNameSet {
-
-public char[][] names;
-public int elementSize; // number of elements in the table
-public int threshold;
-
-PackageNameSet(int size) {
- this.elementSize = 0;
- this.threshold = size; // size represents the expected number of elements
- int extraRoom = (int) (size * 1.5f);
- if (this.threshold == extraRoom)
- extraRoom++;
- this.names = new char[extraRoom][];
-}
-
-char[] add(char[] name) {
- int length = names.length;
- int index = CharOperation.hashCode(name) % length;
- char[] current;
- while ((current = names[index]) != null) {
- if (CharOperation.equals(current, name)) return current;
- if (++index == length) index = 0;
- }
- names[index] = name;
-
- // assumes the threshold is never equal to the size of the table
- if (++elementSize > threshold) rehash();
- return name;
-}
-
-void rehash() {
- PackageNameSet newSet = new PackageNameSet(elementSize * 2); // double the number of expected elements
- char[] current;
- for (int i = names.length; --i >= 0;)
- if ((current = names[i]) != null)
- newSet.add(current);
-
- this.names = newSet.names;
- this.elementSize = newSet.elementSize;
- this.threshold = newSet.threshold;
-}
-}
-
-/*
- * Create index key for type declaration pattern:
- * key = typeName / packageName / enclosingTypeName / modifiers
- * or for secondary types
- * key = typeName / packageName / enclosingTypeName / modifiers / 'S'
- */
-public static char[] createIndexKey(int modifiers, char[] typeName, char[] packageName, char[][] enclosingTypeNames, boolean secondary) { //, char typeSuffix) {
- int typeNameLength = typeName == null ? 0 : typeName.length;
- int packageLength = packageName == null ? 0 : packageName.length;
- int enclosingNamesLength = 0;
- if (enclosingTypeNames != null) {
- for (int i = 0, length = enclosingTypeNames.length; i < length;) {
- enclosingNamesLength += enclosingTypeNames[i].length;
- if (++i < length)
- enclosingNamesLength++; // for the '.' separator
- }
- }
-
- int resultLength = typeNameLength + packageLength + enclosingNamesLength + 5;
- if (secondary) resultLength += 2;
- char[] result = new char[resultLength];
- int pos = 0;
- if (typeNameLength > 0) {
- System.arraycopy(typeName, 0, result, pos, typeNameLength);
- pos += typeNameLength;
- }
- result[pos++] = SEPARATOR;
- if (packageLength > 0) {
- System.arraycopy(packageName, 0, result, pos, packageLength);
- pos += packageLength;
- }
- result[pos++] = SEPARATOR;
- if (enclosingTypeNames != null && enclosingNamesLength > 0) {
- for (int i = 0, length = enclosingTypeNames.length; i < length;) {
- char[] enclosingName = enclosingTypeNames[i];
- int itsLength = enclosingName.length;
- System.arraycopy(enclosingName, 0, result, pos, itsLength);
- pos += itsLength;
- if (++i < length)
- result[pos++] = '.';
- }
- }
- result[pos++] = SEPARATOR;
- result[pos++] = (char) modifiers;
- result[pos] = (char) (modifiers>>16);
- if (secondary) {
- result[++pos] = SEPARATOR;
- result[++pos] = 'S';
- }
- return result;
-}
-
-public TypeDeclarationPattern(
- char[] pkg,
- char[][] enclosingTypeNames,
- char[] simpleName,
- char typeSuffix,
- int matchRule) {
-
- this(matchRule);
-
- int index;
- if (simpleName!=null && (index=CharOperation.lastIndexOf('.',simpleName)) >0)
- {
- pkg=CharOperation.subarray(simpleName, 0, index);
-// simpleName=CharOperation.subarray(simpleName, index+1, simpleName.length);
- }
-
- this.pkg = isCaseSensitive() ? pkg : CharOperation.toLowerCase(pkg);
- if (isCaseSensitive() || enclosingTypeNames == null) {
- this.enclosingTypeNames = enclosingTypeNames;
- } else {
- int length = enclosingTypeNames.length;
- this.enclosingTypeNames = new char[length][];
- for (int i = 0; i < length; i++)
- this.enclosingTypeNames[i] = CharOperation.toLowerCase(enclosingTypeNames[i]);
- }
- this.simpleName = (isCaseSensitive() || isCamelCase()) ? simpleName : CharOperation.toLowerCase(simpleName);
- this.typeSuffix = typeSuffix;
-
- ((InternalSearchPattern)this).mustResolve = (this.pkg != null && this.enclosingTypeNames != null) || typeSuffix != TYPE_SUFFIX;
-}
-TypeDeclarationPattern(int matchRule) {
- super(TYPE_DECL_PATTERN, matchRule);
-}
-/*
- * Type entries are encoded as:
- * simpleTypeName / packageName / enclosingTypeName / modifiers
- * e.g. Object/java.lang//0
- * e.g. Cloneable/java.lang//512
- * e.g. LazyValue/javax.swing/UIDefaults/0
- * or for secondary types as:
- * simpleTypeName / packageName / enclosingTypeName / modifiers / S
- */
-public void decodeIndexKey(char[] key) {
- int slash = CharOperation.indexOf(SEPARATOR, key, 0);
- this.simpleName = CharOperation.subarray(key, 0, slash);
-
- int start = ++slash;
- if (key[start] == SEPARATOR) {
- this.pkg = CharOperation.NO_CHAR;
- } else {
- slash = CharOperation.indexOf(SEPARATOR, key, start);
- this.pkg = internedPackageNames.add(CharOperation.subarray(key, start, slash));
- }
-
- // Continue key read by the end to decode modifiers
- int last = key.length-1;
- this.secondary = key[last] == 'S';
- if (this.secondary) {
- last -= 2;
- }
- this.modifiers = key[last-1] + (key[last]<<16);
- decodeModifiers();
-
- // Retrieve enclosing type names
- start = slash + 1;
- last -= 2; // position of ending slash
- if (start == last) {
- this.enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
- } else {
- if (last == (start+1) && key[start] == ZERO_CHAR) {
- this.enclosingTypeNames = ONE_ZERO_CHAR;
- } else {
- this.enclosingTypeNames = CharOperation.splitOn('.', key, start, last);
- }
- }
-}
-protected void decodeModifiers() {
- this.typeSuffix = CLASS_SUFFIX;
-}
-public SearchPattern getBlankPattern() {
- return new TypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
-}
-public char[][] getIndexCategories() {
- return CATEGORIES;
-}
-public boolean matchesDecodedKey(SearchPattern decodedPattern) {
- TypeDeclarationPattern pattern = (TypeDeclarationPattern) decodedPattern;
-
- // check type suffix
- if (this.typeSuffix != pattern.typeSuffix && typeSuffix != TYPE_SUFFIX) {
- if (!matchDifferentTypeSuffixes(this.typeSuffix, pattern.typeSuffix)) {
- return false;
- }
- }
-
- // check name
- if (!matchesName(this.simpleName, pattern.simpleName))
- return false;
-
- // check package - exact match only
- //if (this.pkg != null && !CharOperation.equals(this.pkg, pattern.pkg, isCaseSensitive()))
- //return false;
-
- // check enclosingTypeNames - exact match only
- if (this.enclosingTypeNames != null) {
- if (this.enclosingTypeNames.length == 0)
- return pattern.enclosingTypeNames.length == 0;
- if (this.enclosingTypeNames.length == 1 && pattern.enclosingTypeNames.length == 1)
- return CharOperation.equals(this.enclosingTypeNames[0], pattern.enclosingTypeNames[0], isCaseSensitive());
- if (pattern.enclosingTypeNames == ONE_ZERO_CHAR)
- return true; // is a local or anonymous type
- return CharOperation.equals(this.enclosingTypeNames, pattern.enclosingTypeNames, isCaseSensitive());
- }
- return true;
-}
-EntryResult[] queryIn(Index index) throws IOException {
- char[] key = this.simpleName; // can be null
- int matchRule = getMatchRule();
-
- switch(getMatchMode()) {
- case R_PREFIX_MATCH :
- // do a prefix query with the simpleName
- break;
- case R_EXACT_MATCH :
- if (this.isCamelCase) break;
- matchRule &= ~R_EXACT_MATCH;
- if (this.simpleName != null) {
- matchRule |= R_PREFIX_MATCH;
- key = this.pkg == null
- ? CharOperation.append(this.simpleName, SEPARATOR)
- : CharOperation.concat(this.simpleName, SEPARATOR, this.pkg, SEPARATOR, CharOperation.NO_CHAR);
- break; // do a prefix query with the simpleName and possibly the pkg
- }
- matchRule |= R_PATTERN_MATCH;
- // fall thru to encode the key and do a pattern query
- case R_PATTERN_MATCH :
- if (this.pkg == null) {
- if (this.simpleName == null) {
- switch(this.typeSuffix) {
- case CLASS_SUFFIX :
- // null key already returns all types
- // key = new char[] {ONE_STAR[0], SEPARATOR, ONE_STAR[0]};
- break;
- }
- } else if (this.simpleName[this.simpleName.length - 1] != '*') {
- key = CharOperation.concat(this.simpleName, ONE_STAR, SEPARATOR);
- }
- break; // do a pattern query with the current encoded key
- }
- // must decode to check enclosingTypeNames due to the encoding of local types
- key = CharOperation.concat(
- this.simpleName == null ? ONE_STAR : this.simpleName, SEPARATOR, this.pkg, SEPARATOR, ONE_STAR);
- break;
- case R_REGEXP_MATCH :
- // TODO (frederic) implement regular expression match
- break;
- }
-
- return index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
-}
-protected StringBuffer print(StringBuffer output) {
- switch (this.typeSuffix){
- case CLASS_SUFFIX :
- output.append("ClassDeclarationPattern: pkg<"); //$NON-NLS-1$
- break;
- default :
- output.append("TypeDeclarationPattern: pkg<"); //$NON-NLS-1$
- break;
- }
- if (pkg != null)
- output.append(pkg);
- else
- output.append("*"); //$NON-NLS-1$
- output.append(">, enclosing<"); //$NON-NLS-1$
- if (enclosingTypeNames != null) {
- for (int i = 0; i < enclosingTypeNames.length; i++){
- output.append(enclosingTypeNames[i]);
- if (i < enclosingTypeNames.length - 1)
- output.append('.');
- }
- } else {
- output.append("*"); //$NON-NLS-1$
- }
- output.append(">, type<"); //$NON-NLS-1$
- if (simpleName != null)
- output.append(simpleName);
- else
- output.append("*"); //$NON-NLS-1$
- output.append(">"); //$NON-NLS-1$
- return super.print(output);
-}
-}
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Michael Spector <spektom@gmail.com> Bug 242987
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.wst.jsdt.core.compiler.CharOperation;
+import org.eclipse.wst.jsdt.core.search.SearchPattern;
+import org.eclipse.wst.jsdt.internal.compiler.classfmt.ClassFileConstants;
+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;
+
+/**
+ * <p>Search pattern used to find and create type declaration index entries.</p>
+ */
+public class TypeDeclarationPattern extends JavaSearchPattern {
+ /**
+ * <p>Qualification of the type declaration.</p>
+ */
+ public char[] qualification;
+
+ /**
+ * <p>Simple type name of the type declaration .</p>
+ */
+ public char[] simpleName;
+
+ /**
+ * <p>Super types of the type declaration.</p>
+ */
+ public char[][] superTypes;
+
+ /**
+ * @deprecated this will be removed at some point because it does not apply to JavaScript and is not longer used internally
+ */
+ public char[][] enclosingTypeNames;
+
+ /**
+ * <p><b>Optional</b></p>
+ *
+ * <p>Any modifiers for this type declaration.</p>
+ *
+ * @see ClassFileConstants
+ */
+ public int modifiers;
+
+ /**
+ * <p>Used when searing for type declarations using a given prefix.
+ * This prefix will be used to match on either the {@link TypeDeclarationPattern#qualification}
+ * or the {@link TypeDeclarationPattern#simpleName}.</p>
+ *
+ * @see #TypeDeclarationPattern(char[], int)
+ *
+ * @see TypeDeclarationPattern#qualification
+ * @see TypeDeclarationPattern#simpleName
+ */
+ private char[] fSearchPrefix;
+
+ /**
+ * <p>Categories to search in for matches in the index.</p>
+ */
+ private static char[][] CATEGORIES = { TYPE_DECL };
+
+
+ /**
+ * <p>Internal constructor for creating plank patterns</p>
+ *
+ * @param matchRule match rule used when comparing this pattern to search results
+ */
+ TypeDeclarationPattern(int matchRule) {
+ super(TYPE_DECL_PATTERN, matchRule);
+ }
+
+ /**
+ * <p>Constructor to use when searching for a type with a specific simple name and qualification.</p>
+ *
+ * @param qualification optional qualification of the type, if not specified then the type
+ * does not have a qualification.
+ * @param simpleName simple type name of the type
+ * @param matchRule match rule used when comparing this pattern to search results
+ */
+ public TypeDeclarationPattern(
+ char[] qualification,
+ char[] simpleName,
+ int matchRule) {
+
+ this(qualification, simpleName, null, matchRule);
+ }
+
+ /**
+ * <p>Constructor to create a pattern using qualification, simple name, and super types.</p>
+ *
+ * @param qualification optional qualification of the type, if not specified then the type
+ * does not have a qualification.
+ * @param simpleName simple type name of the type
+ * @param superTypes
+ * @param matchRule match rule used when comparing this pattern to search results
+ */
+ public TypeDeclarationPattern(
+ char[] qualification,
+ char[] simpleName,
+ char[][] superTypes,
+ int matchRule) {
+
+ this(matchRule);
+
+ /* if someone past a fully qualified name as the simple name break it up, should not have to do this
+ * else initialize normally
+ */
+ if((qualification == null || qualification.length == 0) && CharOperation.contains(DOT, simpleName)) {
+ char[][] seperated = QualificationHelpers.seperateFullyQualifedName(simpleName);
+ this.qualification = seperated[QualificationHelpers.QULIFIERS_INDEX];
+ this.simpleName = seperated[QualificationHelpers.SIMPLE_NAMES_INDEX];
+ } else {
+ if(qualification != null && qualification.length > 0) {
+ this.qualification = qualification;
+ } else {
+ this.qualification = null;
+ }
+ this.simpleName = simpleName;
+ }
+
+ //deal with case sensitive and camel case
+ this.qualification = (isCaseSensitive() || isCamelCase()) ? this.qualification : CharOperation.toLowerCase(this.qualification);
+ this.simpleName = (isCaseSensitive() || isCamelCase()) ? this.simpleName : CharOperation.toLowerCase(this.simpleName);
+
+
+ this.superTypes = superTypes;
+ }
+
+ /**
+ * <p>Constructor to use when searching for a type declaration based on a given prefix.</p>
+ *
+ * @param searchPrefix to match against either the fully qualified name or simple name of
+ * type declarations
+ * @param matchRule match rule used when comparing this pattern to search results
+ */
+ public TypeDeclarationPattern(char[] searchPrefix, int matchRule) {
+ this(matchRule);
+
+ this.fSearchPrefix = (isCaseSensitive() || isCamelCase()) ? searchPrefix : CharOperation.toLowerCase(searchPrefix);
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.core.search.SearchPattern#decodeIndexKey(char[])
+ * @see #createIndexKey(char[], char[][], int)
+ */
+ public void decodeIndexKey(char[] key) {
+ char[][] seperated = CharOperation.splitOn(SEPARATOR, key);
+
+ //decode type name
+ this.simpleName = seperated[0];
+ this.qualification = seperated[1];
+
+ //get super types
+ this.superTypes = CharOperation.splitOn(PARAMETER_SEPARATOR, seperated[2]);
+
+ //get the modifiers
+ this.modifiers = seperated[3][0] + seperated[3][1];
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.internal.core.search.matching.JavaSearchPattern#getBlankPattern()
+ */
+ public SearchPattern getBlankPattern() {
+ return new TypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.core.search.SearchPattern#getIndexCategories()
+ */
+ public char[][] getIndexCategories() {
+ return CATEGORIES;
+ }
+
+ /**
+ * <p>Matches this pattern against another pattern using the following logic:<ul>
+ * <li>OR<ul>
+ * <li>AND<ul>
+ * <li>this pattern has a defined search prefix</li>
+ * <li>OR<ul>
+ * <li>this pattern's prefix matches the other patterns qualified name</li>
+ * <li>this pattern's prefix matches the other patterns simple name</li>
+ * <li>AND if after separating this pattern's prefix into a qualifier and simple name<ul>
+ * <li>this pattern's prefix qualifier matches the other patterns qualified name</li>
+ * <li>this pattern's prefix simple name matches the other patterns simple name</li></ul></li></ul></li></ul></li>
+ * <li>AND<ul>
+ * <li>this pattern does not have a defined search prefix</li>
+ * <li>this pattern's qualified name equals the other patterns qualified name</li>
+ * <li>this pattern's simple name equals the other patterns simple name</li></ul></li></ul></li></ul></li></ul></p>
+ *
+ * @see org.eclipse.wst.jsdt.core.search.SearchPattern#matchesDecodedKey(org.eclipse.wst.jsdt.core.search.SearchPattern)
+ */
+ public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+ TypeDeclarationPattern pattern = (TypeDeclarationPattern) decodedPattern;
+ char[][] seperatedSearchPrefix = QualificationHelpers.seperateFullyQualifedName(this.fSearchPrefix);
+
+ return
+ (
+ this.fSearchPrefix != null &&
+ (
+ matchesName(this.fSearchPrefix, CharOperation.append(pattern.qualification, '.')) ||
+ matchesName(this.fSearchPrefix, pattern.simpleName) ||
+ (
+ (
+ CharOperation.equals(seperatedSearchPrefix[QualificationHelpers.QULIFIERS_INDEX], pattern.qualification, isCaseSensitive) ||
+ matchesQualificationPattern(seperatedSearchPrefix[QualificationHelpers.QULIFIERS_INDEX], pattern.qualification, isCaseSensitive)
+ ) &&
+ matchesName(seperatedSearchPrefix[QualificationHelpers.SIMPLE_NAMES_INDEX], pattern.simpleName)
+ )
+ )
+ )
+ ||
+ (
+ this.fSearchPrefix == null &&
+ matchesName(this.qualification, pattern.qualification) &&
+ matchesName(this.simpleName, pattern.simpleName)
+ )
+ ||
+ (
+ this.fSearchPrefix == null && this.superTypes != null &&
+ matchesName(this.superTypes, pattern.superTypes)
+ );
+ }
+
+ /**
+ * @param superTypes
+ * @param patternSuperTypes
+ * @return
+ */
+ private boolean matchesName(char[][] superTypes, char[][] patternSuperTypes) {
+ for (int i = 0; i < superTypes.length; i++) {
+ for (int j = 0; j < patternSuperTypes.length; j++) {
+ if (matchesName(this.superTypes[i], patternSuperTypes[j]))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @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 {
+ EntryResult[] results = null;
+
+ //determine the qualification and simple name patterns to use
+ char[] qualificationPattern;
+ char[] simpleNamePattern;
+ if(this.fSearchPrefix != null) {
+ char[][] seperatedSearchPrefix = QualificationHelpers.seperateFullyQualifedName(this.fSearchPrefix);
+ qualificationPattern = seperatedSearchPrefix[QualificationHelpers.QULIFIERS_INDEX];
+ simpleNamePattern = seperatedSearchPrefix[QualificationHelpers.SIMPLE_NAMES_INDEX];
+ } else {
+ qualificationPattern = this.qualification;
+ simpleNamePattern = this.simpleName;
+ }
+
+ //might have to do multiple searches
+ char[][] keys = null;
+ int[] matchRules = null;
+
+ switch(getMatchMode()) {
+ case R_EXACT_MATCH :
+ keys = new char[1][];
+ matchRules = new int[1];
+ //can not do an exact match with camel case
+ if (this.isCamelCase) break;
+
+ /* doing an exact match on the type, but really doing a prefix match in the index for
+ * simpleName// or simpleName/qualification/
+ */
+
+ if(qualificationPattern == null || qualificationPattern.length == 0) {
+ keys[0] = CharOperation.append(simpleNamePattern, SEPARATOR);
+ } else {
+ keys[0] = CharOperation.concat(simpleNamePattern, qualificationPattern, SEPARATOR);
+ }
+
+ keys[0] = CharOperation.append(keys[0], SEPARATOR);
+ if (superTypes != null)
+ keys[0] = CharOperation.concat(keys[0], CharOperation.concatWith(superTypes, PARAMETER_SEPARATOR));
+
+ matchRules[0] = this.getMatchRule();
+ matchRules[0] &= ~R_EXACT_MATCH;
+ matchRules[0] |= R_PREFIX_MATCH;
+ break;
+ case R_PREFIX_MATCH :
+ if(qualificationPattern != null && qualificationPattern.length > 0) {
+ if(simpleNamePattern == null || simpleNamePattern.length == 0) {
+ keys = new char[1][];
+ matchRules = new int[1];
+ } else {
+ keys = new char[2][];
+ matchRules = new int[2];
+
+ /* search just simple name because can not search camel case simple name with qualification:
+ * simpleNamePattern
+ */
+ keys[1] = simpleNamePattern;
+ matchRules[1] = this.getMatchRule();
+ }
+
+ /* do a pattern search using the entire pattern as the qualification:
+ * * /fSearchPrefix*
+ */
+ char[] trimmedPrefix = this.fSearchPrefix;
+ if(this.fSearchPrefix != null && this.fSearchPrefix[this.fSearchPrefix.length - 1] == DOT) {
+ trimmedPrefix = CharOperation.subarray(this.fSearchPrefix, 0, this.fSearchPrefix.length - 1);
+ }
+
+ keys[0] = CharOperation.concat(ONE_STAR, trimmedPrefix, SEPARATOR);
+ keys[0] = CharOperation.concat(keys[0], ONE_STAR);
+ if (superTypes != null)
+ keys[0] = CharOperation.concat(keys[0], CharOperation.concatWith(superTypes, PARAMETER_SEPARATOR));
+ matchRules[0] = this.getMatchRule();
+ matchRules[0] &= ~R_PREFIX_MATCH;
+ matchRules[0] |= R_PATTERN_MATCH;
+ } else {
+ if(simpleNamePattern == null || simpleNamePattern.length == 0) {
+ keys = new char[1][];
+ matchRules = new int[1];
+ } else {
+ keys = new char[2][];
+ matchRules = new int[2];
+
+ /* first key to search for is using the simple name as the simple name using prefix match:
+ * simpleNamePattern
+ */
+ keys[1] = simpleNamePattern;
+ matchRules[1] = this.getMatchRule();
+ }
+
+ /* second key to search for is using the simple name as the qualifier using a pattern match
+ * * /simpleNamePattern*
+ */
+ keys[0] = CharOperation.concat(ONE_STAR, simpleNamePattern, SEPARATOR);
+ keys[0] = CharOperation.concat(keys[0], ONE_STAR);
+ matchRules[0] = this.getMatchRule();
+ matchRules[0] &= ~R_PREFIX_MATCH;
+ matchRules[0] |= R_PATTERN_MATCH;
+ }
+
+ break;
+ case R_PATTERN_MATCH :
+ /* create the pattern:
+ * simpleNamePattern/qualificationPattern/*
+ */
+ if (this.fSearchPrefix != null) {
+ keys = new char[2][];
+ matchRules = new int[2];
+
+ /* Key to search for is using the entire pattern as the qualification:
+ * * /fSearchPrefix/*
+ */
+ keys[1] = CharOperation.concat(ONE_STAR, this.fSearchPrefix, SEPARATOR);
+ keys[1] = CharOperation.concat(keys[1], ONE_STAR, SEPARATOR);
+ matchRules[1] = this.getMatchRule();
+ } else {
+ keys = new char[1][];
+ matchRules = new int[1];
+ }
+
+ //if no simple name use *
+ if (simpleNamePattern == null || simpleNamePattern.length == 0) {
+ simpleNamePattern = ONE_STAR;
+ }
+
+ //if no qualification use *
+ if (qualificationPattern == null || qualificationPattern.length == 0) {
+ qualificationPattern = ONE_STAR;
+ }
+
+ /* Key to search for is using the simple name of the pattern as the simple name
+ * simpleNamePattern/qualificationPattern/*
+ */
+ keys[0] = CharOperation.concat(simpleNamePattern, qualificationPattern, SEPARATOR);
+ if (superTypes != null) {
+ // account for modifier values in #createIndexKey() by appending an extra SEPARATOR and ONE_STAR
+ keys[0] = CharOperation.concat(keys[0], SEPARATOR, CharOperation.concatWith(superTypes, PARAMETER_SEPARATOR), SEPARATOR, ONE_STAR);
+ }
+ else {
+ keys[0] = CharOperation.concat(keys[0], ONE_STAR, SEPARATOR);
+ }
+ matchRules[0] = this.getMatchRule();
+
+ break;
+ case R_REGEXP_MATCH :
+ Logger.log(Logger.WARNING, "Regular expression matching is not implimented by ConstructorDeclarationPattern");
+ break;
+ }
+
+ //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;
+ }
+
+ /**
+ * @see org.eclipse.wst.jsdt.internal.core.search.matching.JavaSearchPattern#print(java.lang.StringBuffer)
+ */
+ protected StringBuffer print(StringBuffer output) {
+ if (qualification != null)
+ output.append(qualification);
+ else
+ output.append("*"); //$NON-NLS-1$
+
+ if (simpleName != null)
+ output.append(simpleName);
+ else
+ output.append("*"); //$NON-NLS-1$
+ output.append(">"); //$NON-NLS-1$
+ return super.print(output);
+ }
+
+ /**
+ * <p>Creates a type declaration index key, based on the given information, to be placed in the index.</p>
+ *
+ * <p><b>Key Syntax</b>:
+ * <code>simpleName/qualification/fullyQualifiedSuperTypeNames/modifiers</code></p>
+ *
+ * @param qualification optional qualification of the type, if not specified then the type
+ * does not have a qualification.
+ * @param simpleName simple type name of the type
+ * @param fullyQualifiedSuperTypeNames list of fully qualified super type names
+ * @param modifiers Modifiers to the type declaration
+ *
+ * @return Type declaration index key
+ */
+ public static char[] createIndexKey(char[] qualification, char[] simpleName, char[][] fullyQualifiedSuperTypeNames, int modifiers) {
+ char[] indexKey = null;
+
+ if(simpleName != null) {
+ //build list of super types
+ char[] fullyQualifiedSuperTypeNamesList = null;
+ if(fullyQualifiedSuperTypeNames != null) {
+ fullyQualifiedSuperTypeNamesList = CharOperation.concatWith(fullyQualifiedSuperTypeNames, PARAMETER_SEPARATOR);
+ } else {
+ fullyQualifiedSuperTypeNamesList = CharOperation.NO_CHAR;
+ }
+
+ //get lengths
+ int simpleNameLength = simpleName.length;
+ int qualificationLength = qualification == null ? 0 : qualification.length;
+
+ //get length
+ int keyLength = simpleNameLength
+ + 1 + qualificationLength
+ + 1 + fullyQualifiedSuperTypeNamesList.length
+ + 3; //modifiers
+
+ //create result char array
+ indexKey = new char[keyLength];
+
+ //add simple type name to result
+ int pos = 0;
+ if (simpleNameLength > 0) {
+ System.arraycopy(simpleName, 0, indexKey, pos, simpleNameLength);
+ pos += simpleNameLength;
+ }
+
+ //add qualification to result
+ indexKey[pos++] = SEPARATOR;
+ if (qualificationLength > 0) {
+ System.arraycopy(qualification, 0, indexKey, pos, qualificationLength);
+ pos += qualificationLength;
+ }
+
+ //add super types
+ indexKey[pos++] = SEPARATOR;
+ if (fullyQualifiedSuperTypeNamesList.length > 0) {
+ System.arraycopy(fullyQualifiedSuperTypeNamesList, 0, indexKey, pos, fullyQualifiedSuperTypeNamesList.length);
+ pos += fullyQualifiedSuperTypeNamesList.length;
+ }
+
+ //add modifiers
+ indexKey[pos++] = SEPARATOR;
+ indexKey[pos++] = (char) modifiers;
+ indexKey[pos++] = (char) (modifiers>>16);
+ }
+
+ return indexKey;
+ }
+
+ public char[] getSearchPrefix() {
+ return fSearchPrefix;
+ }
+
+}

Back to the top