/******************************************************************************* * 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 } }