blob: 28627412531da7b4ac86d14e051687e49895d223 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching;
import java.io.IOException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.internal.core.index.*;
import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
public class ConstructorPattern extends SearchPattern implements IIndexConstants {
protected boolean findDeclarations;
protected boolean findReferences;
public char[] declaringQualification;
public char[] declaringSimpleName;
public char[][] parameterQualifications;
public char[][] parameterSimpleNames;
public int parameterCount;
protected static char[][] REF_CATEGORIES = { CONSTRUCTOR_REF };
protected static char[][] REF_AND_DECL_CATEGORIES = { CONSTRUCTOR_REF, CONSTRUCTOR_DECL };
protected static char[][] DECL_CATEGORIES = { CONSTRUCTOR_DECL };
/**
* Constructor entries are encoded as TypeName '/' Arity:
* e.g. 'X/0'
*/
public static char[] createIndexKey(char[] typeName, int argCount) {
char[] countChars = argCount < 10
? COUNTS[argCount]
: ("/" + String.valueOf(argCount)).toCharArray(); //$NON-NLS-1$
return CharOperation.concat(typeName, countChars);
}
public ConstructorPattern(
boolean findDeclarations,
boolean findReferences,
char[] declaringSimpleName,
char[] declaringQualification,
char[][] parameterQualifications,
char[][] parameterSimpleNames,
int matchRule) {
this(matchRule);
this.findDeclarations = findDeclarations;
this.findReferences = findReferences;
this.declaringQualification = isCaseSensitive() ? declaringQualification : CharOperation.toLowerCase(declaringQualification);
this.declaringSimpleName = isCaseSensitive() ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
if (parameterSimpleNames != null) {
this.parameterCount = parameterSimpleNames.length;
this.parameterQualifications = new char[this.parameterCount][];
this.parameterSimpleNames = new char[this.parameterCount][];
for (int i = 0; i < this.parameterCount; i++) {
this.parameterQualifications[i] = isCaseSensitive() ? parameterQualifications[i] : CharOperation.toLowerCase(parameterQualifications[i]);
this.parameterSimpleNames[i] = isCaseSensitive() ? parameterSimpleNames[i] : CharOperation.toLowerCase(parameterSimpleNames[i]);
}
} else {
this.parameterCount = -1;
}
((InternalSearchPattern)this).mustResolve = mustResolve();
}
ConstructorPattern(int matchRule) {
super(CONSTRUCTOR_PATTERN, matchRule);
}
public void decodeIndexKey(char[] key) {
int size = key.length;
int lastSeparatorIndex = CharOperation.lastIndexOf(SEPARATOR, key);
this.parameterCount = Integer.parseInt(new String(key, lastSeparatorIndex + 1, size - lastSeparatorIndex - 1));
this.declaringSimpleName = CharOperation.subarray(key, 0, lastSeparatorIndex);
}
public SearchPattern getBlankPattern() {
return new ConstructorPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
}
public char[][] getMatchCategories() {
if (this.findReferences)
return this.findDeclarations ? REF_AND_DECL_CATEGORIES : REF_CATEGORIES;
if (this.findDeclarations)
return DECL_CATEGORIES;
return CharOperation.NO_CHAR_CHAR;
}
public boolean matchesDecodedKey(SearchPattern decodedPattern) {
ConstructorPattern pattern = (ConstructorPattern) decodedPattern;
return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1)
&& matchesName(this.declaringSimpleName, pattern.declaringSimpleName);
}
protected boolean mustResolve() {
if (this.declaringQualification != null) return true;
// parameter types
if (this.parameterSimpleNames != null)
for (int i = 0, max = this.parameterSimpleNames.length; i < max; i++)
if (this.parameterQualifications[i] != null) return true;
return this.findReferences; // need to check resolved default constructors and explicit constructor calls
}
EntryResult[] queryIn(Index index) throws IOException {
char[] key = this.declaringSimpleName; // can be null
int matchRule = getMatchRule();
switch(getMatchMode()) {
case R_EXACT_MATCH :
if (this.declaringSimpleName != null && this.parameterCount >= 0)
key = createIndexKey(this.declaringSimpleName, this.parameterCount);
else // do a prefix query with the declaringSimpleName
matchRule = matchRule - R_EXACT_MATCH + R_PREFIX_MATCH;
break;
case R_PREFIX_MATCH :
// do a prefix query with the declaringSimpleName
break;
case R_PATTERN_MATCH :
if (this.parameterCount >= 0)
key = createIndexKey(this.declaringSimpleName == null ? ONE_STAR : this.declaringSimpleName, this.parameterCount);
else if (this.declaringSimpleName != null && this.declaringSimpleName[this.declaringSimpleName.length - 1] != '*')
key = CharOperation.concat(this.declaringSimpleName, ONE_STAR, SEPARATOR);
// else do a pattern query with just the declaringSimpleName
break;
}
return index.query(getMatchCategories(), key, matchRule); // match rule is irrelevant when the key is null
}
public String toString() {
StringBuffer buffer = new StringBuffer(20);
if (this.findDeclarations) {
buffer.append(this.findReferences
? "ConstructorCombinedPattern: " //$NON-NLS-1$
: "ConstructorDeclarationPattern: "); //$NON-NLS-1$
} else {
buffer.append("ConstructorReferencePattern: "); //$NON-NLS-1$
}
if (declaringQualification != null)
buffer.append(declaringQualification).append('.');
if (declaringSimpleName != null)
buffer.append(declaringSimpleName);
else if (declaringQualification != null)
buffer.append("*"); //$NON-NLS-1$
buffer.append('(');
if (parameterSimpleNames == null) {
buffer.append("..."); //$NON-NLS-1$
} else {
for (int i = 0, max = parameterSimpleNames.length; i < max; i++) {
if (i > 0) buffer.append(", "); //$NON-NLS-1$
if (parameterQualifications[i] != null) buffer.append(parameterQualifications[i]).append('.');
if (parameterSimpleNames[i] == null) buffer.append('*'); else buffer.append(parameterSimpleNames[i]);
}
}
buffer.append(')');
buffer.append(", "); //$NON-NLS-1$
switch(getMatchMode()) {
case R_EXACT_MATCH :
buffer.append("exact match, "); //$NON-NLS-1$
break;
case R_PREFIX_MATCH :
buffer.append("prefix match, "); //$NON-NLS-1$
break;
case R_PATTERN_MATCH :
buffer.append("pattern match, "); //$NON-NLS-1$
break;
}
buffer.append(isCaseSensitive() ? "case sensitive" : "case insensitive"); //$NON-NLS-1$ //$NON-NLS-2$
return buffer.toString();
}
}