| /******************************************************************************* |
| * 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 JavaSearchPattern implements IIndexConstants { |
| |
| protected boolean findDeclarations; |
| protected boolean findReferences; |
| |
| public char[] declaringQualification; |
| public char[] declaringSimpleName; |
| |
| public char[][] parameterQualifications; |
| public char[][] parameterSimpleNames; |
| public int parameterCount; |
| public boolean varargs; |
| |
| 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, |
| boolean varargs, |
| 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; |
| } |
| this.varargs = varargs; |
| ((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[][] getIndexCategories() { |
| 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 || this.varargs) |
| && 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.varargs && 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.varargs && 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(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null |
| } |
| protected StringBuffer print(StringBuffer output) { |
| if (this.findDeclarations) { |
| output.append(this.findReferences |
| ? "ConstructorCombinedPattern: " //$NON-NLS-1$ |
| : "ConstructorDeclarationPattern: "); //$NON-NLS-1$ |
| } else { |
| output.append("ConstructorReferencePattern: "); //$NON-NLS-1$ |
| } |
| if (declaringQualification != null) |
| output.append(declaringQualification).append('.'); |
| if (declaringSimpleName != null) |
| output.append(declaringSimpleName); |
| else if (declaringQualification != null) |
| output.append("*"); //$NON-NLS-1$ |
| |
| output.append('('); |
| if (parameterSimpleNames == null) { |
| output.append("..."); //$NON-NLS-1$ |
| } else { |
| for (int i = 0, max = parameterSimpleNames.length; i < max; i++) { |
| if (i > 0) output.append(", "); //$NON-NLS-1$ |
| if (parameterQualifications[i] != null) output.append(parameterQualifications[i]).append('.'); |
| if (parameterSimpleNames[i] == null) output.append('*'); else output.append(parameterSimpleNames[i]); |
| } |
| } |
| output.append(')'); |
| return super.print(output); |
| } |
| } |