001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.core.search.matching;
011:
012: import org.eclipse.jdt.core.compiler.CharOperation;
013: import org.eclipse.jdt.core.search.*;
014: import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
015:
016: public class QualifiedTypeDeclarationPattern extends
017: TypeDeclarationPattern implements IIndexConstants {
018:
019: public char[] qualification;
020: PackageDeclarationPattern packagePattern;
021: public int packageIndex = -1;
022:
023: public QualifiedTypeDeclarationPattern(char[] qualification,
024: char[] simpleName, char typeSuffix, int matchRule) {
025: this (matchRule);
026:
027: this .qualification = this .isCaseSensitive ? qualification
028: : CharOperation.toLowerCase(qualification);
029: this .simpleName = (this .isCaseSensitive || this .isCamelCase) ? simpleName
030: : CharOperation.toLowerCase(simpleName);
031: this .typeSuffix = typeSuffix;
032:
033: ((InternalSearchPattern) this ).mustResolve = this .qualification != null
034: || typeSuffix != TYPE_SUFFIX;
035: }
036:
037: public QualifiedTypeDeclarationPattern(char[] qualification,
038: int qualificationMatchRule, char[] simpleName,
039: char typeSuffix, int matchRule) {
040: this (qualification, simpleName, typeSuffix, matchRule);
041: this .packagePattern = new PackageDeclarationPattern(
042: qualification, qualificationMatchRule);
043: }
044:
045: QualifiedTypeDeclarationPattern(int matchRule) {
046: super (matchRule);
047: }
048:
049: public void decodeIndexKey(char[] key) {
050: int slash = CharOperation.indexOf(SEPARATOR, key, 0);
051: this .simpleName = CharOperation.subarray(key, 0, slash);
052:
053: int start = ++slash;
054: if (key[start] == SEPARATOR) {
055: this .pkg = CharOperation.NO_CHAR;
056: } else {
057: slash = CharOperation.indexOf(SEPARATOR, key, start);
058: this .pkg = internedPackageNames.add(CharOperation.subarray(
059: key, start, slash));
060: }
061: this .qualification = this .pkg;
062:
063: // Continue key read by the end to decode modifiers
064: int last = key.length - 1;
065: this .secondary = key[last] == 'S';
066: if (this .secondary) {
067: last -= 2;
068: }
069: this .modifiers = key[last - 1] + (key[last] << 16);
070: decodeModifiers();
071:
072: // Retrieve enclosing type names
073: start = slash + 1;
074: last -= 2; // position of ending slash
075: if (start == last) {
076: this .enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
077: } else {
078: int length = this .qualification.length;
079: int size = last - start;
080: System.arraycopy(this .qualification, 0,
081: this .qualification = new char[length + 1 + size],
082: 0, length);
083: this .qualification[length] = '.';
084: if (last == (start + 1) && key[start] == ZERO_CHAR) {
085: this .enclosingTypeNames = ONE_ZERO_CHAR;
086: this .qualification[length + 1] = ZERO_CHAR;
087: } else {
088: this .enclosingTypeNames = CharOperation.splitOn('.',
089: key, start, last);
090: System.arraycopy(key, start, this .qualification,
091: length + 1, size);
092: }
093: }
094: }
095:
096: public SearchPattern getBlankPattern() {
097: return new QualifiedTypeDeclarationPattern(R_EXACT_MATCH
098: | R_CASE_SENSITIVE);
099: }
100:
101: public boolean matchesDecodedKey(SearchPattern decodedPattern) {
102: QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
103:
104: // check type suffix
105: if (this .typeSuffix != pattern.typeSuffix
106: && typeSuffix != TYPE_SUFFIX) {
107: if (!matchDifferentTypeSuffixes(this .typeSuffix,
108: pattern.typeSuffix)) {
109: return false;
110: }
111: }
112:
113: // check name
114: return matchesName(this .simpleName, pattern.simpleName)
115: && (this .qualification == null
116: || this .packagePattern == null || this .packagePattern
117: .matchesName(this .qualification,
118: pattern.qualification));
119: }
120:
121: protected StringBuffer print(StringBuffer output) {
122: switch (this .typeSuffix) {
123: case CLASS_SUFFIX:
124: output.append("ClassDeclarationPattern: qualification<"); //$NON-NLS-1$
125: break;
126: case CLASS_AND_INTERFACE_SUFFIX:
127: output
128: .append("ClassAndInterfaceDeclarationPattern: qualification<"); //$NON-NLS-1$
129: break;
130: case CLASS_AND_ENUM_SUFFIX:
131: output
132: .append("ClassAndEnumDeclarationPattern: qualification<"); //$NON-NLS-1$
133: break;
134: case INTERFACE_SUFFIX:
135: output
136: .append("InterfaceDeclarationPattern: qualification<"); //$NON-NLS-1$
137: break;
138: case INTERFACE_AND_ANNOTATION_SUFFIX:
139: output
140: .append("InterfaceAndAnnotationDeclarationPattern: qualification<"); //$NON-NLS-1$
141: break;
142: case ENUM_SUFFIX:
143: output.append("EnumDeclarationPattern: qualification<"); //$NON-NLS-1$
144: break;
145: case ANNOTATION_TYPE_SUFFIX:
146: output
147: .append("AnnotationTypeDeclarationPattern: qualification<"); //$NON-NLS-1$
148: break;
149: default:
150: output.append("TypeDeclarationPattern: qualification<"); //$NON-NLS-1$
151: break;
152: }
153: if (this .qualification != null)
154: output.append(this .qualification);
155: else
156: output.append("*"); //$NON-NLS-1$
157: output.append(">, type<"); //$NON-NLS-1$
158: if (simpleName != null)
159: output.append(simpleName);
160: else
161: output.append("*"); //$NON-NLS-1$
162: output.append("> "); //$NON-NLS-1$
163: return super.print(output);
164: }
165: }
|