/*******************************************************************************
* Copyright (c) 2009 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
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.internal.compiler.ExtraFlags;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
public class ConstructorDeclarationPattern extends ConstructorPattern {
public int extraFlags;
public int declaringTypeModifiers;
public char[] declaringPackageName;
public int modifiers;
public char[] signature;
public char[][] parameterTypes;
public char[][] parameterNames;
public ConstructorDeclarationPattern(char[] declaringPackageName, char[] declaringSimpleName, int matchRule) {
this(matchRule);
this.declaringSimpleName= (this.isCaseSensitive || this.isCamelCase) ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
this.declaringPackageName= declaringPackageName;
this.findDeclarations= true;
this.findReferences= false;
this.parameterCount= -1;
this.mustResolve= false;
}
ConstructorDeclarationPattern(int matchRule) {
super(matchRule);
}
public void decodeIndexKey(char[] key) {
int last= key.length - 1;
int slash= CharOperation.indexOf(SEPARATOR, key, 0);
this.declaringSimpleName= CharOperation.subarray(key, 0, slash);
int start= slash + 1;
slash= CharOperation.indexOf(SEPARATOR, key, start);
last= slash - 1;
boolean isDefaultConstructor= key[last] == '#';
if (isDefaultConstructor) {
this.parameterCount= -1;
} else {
this.parameterCount= 0;
int power= 1;
for (int i= last; i >= start; i--) {
if (i == last) {
this.parameterCount= key[i] - '0';
} else {
power*= 10;
this.parameterCount+= power * (key[i] - '0');
}
}
}
slash= slash + 3;
last= slash - 1;
int typeModifiersWithExtraFlags= key[last - 1] + (key[last] << 16);
this.declaringTypeModifiers= decodeModifers(typeModifiersWithExtraFlags);
this.extraFlags= decodeExtraFlags(typeModifiersWithExtraFlags);
// initialize optional fields
this.declaringPackageName= null;
this.modifiers= 0;
this.signature= null;
this.parameterTypes= null;
this.parameterNames= null;
boolean isMemberType= (this.extraFlags & ExtraFlags.IsMemberType) != 0;
if (!isMemberType) {
start= slash + 1;
if (this.parameterCount == -1) {
slash= key.length;
last= slash - 1;
} else {
slash= CharOperation.indexOf(SEPARATOR, key, start);
}
last= slash - 1;
this.declaringPackageName= CharOperation.subarray(key, start, slash);
start= slash + 1;
if (this.parameterCount == 0) {
slash= slash + 3;
last= slash - 1;
this.modifiers= key[last - 1] + (key[last] << 16);
} else if (this.parameterCount > 0) {
slash= CharOperation.indexOf(SEPARATOR, key, start);
last= slash - 1;
boolean hasParameterStoredAsSignature= (this.extraFlags & ExtraFlags.ParameterTypesStoredAsSignature) != 0;
if (hasParameterStoredAsSignature) {
this.signature= CharOperation.subarray(key, start, slash);
CharOperation.replace(this.signature, '\\', SEPARATOR);
} else {
this.parameterTypes= CharOperation.splitOn(PARAMETER_SEPARATOR, key, start, slash);
}
start= slash + 1;
slash= CharOperation.indexOf(SEPARATOR, key, start);
last= slash - 1;
if (slash != start) {
this.parameterNames= CharOperation.splitOn(PARAMETER_SEPARATOR, key, start, slash);
}
slash= slash + 3;
last= slash - 1;
this.modifiers= key[last - 1] + (key[last] << 16);
} else {
this.modifiers= ClassFileConstants.AccPublic;
}
}
removeInternalFlags(); // remove internal flags
}
public SearchPattern getBlankPattern() {
return new ConstructorDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
}
public char[][] getIndexCategories() {
return DECL_CATEGORIES;
}
public boolean matchesDecodedKey(SearchPattern decodedPattern) {
ConstructorDeclarationPattern pattern= (ConstructorDeclarationPattern)decodedPattern;
// only top level types
if ((pattern.extraFlags & ExtraFlags.IsMemberType) != 0)
return false;
// check package - exact match only
if (this.declaringPackageName != null && !CharOperation.equals(this.declaringPackageName, pattern.declaringPackageName, true))
return false;
return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
&& matchesName(this.declaringSimpleName, pattern.declaringSimpleName);
}
private void removeInternalFlags() {
this.extraFlags= this.extraFlags & ~ExtraFlags.ParameterTypesStoredAsSignature; // ParameterTypesStoredAsSignature is an internal flags only used to decode key
}
}