diff options
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.java | 842 |
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; + }
+
+}
|