matchRule);
}
private static SearchPattern createMethodOrConstructorPattern(String patternString, int limitTo, int matchRule, boolean isConstructor) {
Scanner scanner = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3/*sourceLevel*/, null /*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
scanner.setSource(patternString.toCharArray());
final int InsideSelector = 1;
final int InsideTypeArguments = 2;
final int InsideParameter = 3;
final int InsideReturnType = 4;
int lastToken = -1;
String declaringType = null, selector = null, parameterType = null;
String[] parameterTypes = null;
char[][] typeArguments = null;
String typeArgumentsString = null;
int parameterCount = -1;
String returnType = null;
boolean foundClosingParenthesis = false;
int mode = InsideSelector;
int token, argCount = 0;
try {
token = scanner.getNextToken();
} catch (InvalidInputException e) {
return null;
}
while (token != TerminalTokens.TokenNameEOF) {
switch(mode) {
// read declaring type and selector
case InsideSelector :
if (argCount == 0) {
switch (token) {
case TerminalTokens.TokenNameLESS:
argCount++;
if (selector == null || lastToken == TerminalTokens.TokenNameDOT) {
typeArgumentsString = scanner.getCurrentTokenString();
mode = InsideTypeArguments;
break;
}
if (declaringType == null) {
declaringType = selector;
} else {
declaringType += '.' + selector;
}
declaringType += scanner.getCurrentTokenString();
selector = null;
break;
case TerminalTokens.TokenNameDOT:
if (!isConstructor && typeArgumentsString != null) return null; // invalid syntax
if (declaringType == null) {
if (selector == null) return null; // invalid syntax
declaringType = selector;
} else if (selector != null) {
declaringType += scanner.getCurrentTokenString() + selector;
}
selector = null;
break;
case TerminalTokens.TokenNameLPAREN:
parameterTypes = new String[5];
parameterCount = 0;
mode = InsideParameter;
break;
case TerminalTokens.TokenNameWHITESPACE:
switch (lastToken) {
case TerminalTokens.TokenNameWHITESPACE:
case TerminalTokens.TokenNameDOT:
case TerminalTokens.TokenNameGREATER:
case TerminalTokens.TokenNameRIGHT_SHIFT:
case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
break;
default:
mode = InsideReturnType;
break;
}
break;
default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
if (selector == null)
selector = scanner.getCurrentTokenString();
else
selector += scanner.getCurrentTokenString();
break;
}
} else {
if (declaringType == null) return null; // invalid syntax
switch (token) {
case TerminalTokens.TokenNameGREATER:
case TerminalTokens.TokenNameRIGHT_SHIFT:
case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
argCount--;
break;
case TerminalTokens.TokenNameLESS:
argCount++;
break;
}
declaringType += scanner.getCurrentTokenString();
}
break;
// read type arguments
case InsideTypeArguments:
if (typeArgumentsString == null) return null; // invalid syntax
typeArgumentsString += scanner.getCurrentTokenString();
switch (token) {
case TerminalTokens.TokenNameGREATER:
case TerminalTokens.TokenNameRIGHT_SHIFT:
case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
argCount--;
if (argCount == 0) {
String pseudoType = "Type"+typeArgumentsString; //$NON-NLS-1$
typeArguments = Signature.getTypeArguments(Signature.createTypeSignature(pseudoType, false).toCharArray());
mode = InsideSelector;
}
break;
case TerminalTokens.TokenNameLESS:
argCount++;
break;
}
break;
// read parameter types
case InsideParameter :
if (argCount == 0) {
switch (token) {
case TerminalTokens.TokenNameWHITESPACE:
break;
case TerminalTokens.TokenNameCOMMA:
if (parameterType == null) return null;
if (parameterTypes != null) {
if (parameterTypes.length == parameterCount)
System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
parameterTypes[parameterCount++] = parameterType;
}
parameterType = null;
break;
case TerminalTokens.TokenNameRPAREN:
foundClosingParenthesis = true;
if (parameterType != null && parameterTypes != null) {
if (parameterTypes.length == parameterCount)
System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
parameterTypes[parameterCount++] = parameterType;
}
mode = isConstructor ? InsideTypeArguments : InsideReturnType;
break;
case TerminalTokens.TokenNameLESS:
argCount++;
if (parameterType == null) return null; // invalid syntax
// $FALL-THROUGH$ - fall through next case to add token
default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
if (parameterType == null)
parameterType = scanner.getCurrentTokenString();
else
parameterType += scanner.getCurrentTokenString();
}
} else {
if (parameterType == null) return null; // invalid syntax
switch (token) {
case TerminalTokens.TokenNameGREATER:
case TerminalTokens.TokenNameRIGHT_SHIFT:
case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
argCount--;
break;
case TerminalTokens.TokenNameLESS:
argCount++;
break;
}
parameterType += scanner.getCurrentTokenString();
}
break;
// read return type
case InsideReturnType:
if (argCount == 0) {
switch (token) {
case TerminalTokens.TokenNameWHITESPACE:
break;
case TerminalTokens.TokenNameLPAREN:
parameterTypes = new String[5];
parameterCount = 0;
mode = InsideParameter;
break;
case TerminalTokens.TokenNameLESS:
argCount++;
if (returnType == null) return null; // invalid syntax
// $FALL-THROUGH$ - fall through next case to add token
default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
if (returnType == null)
returnType = scanner.getCurrentTokenString();
else
returnType += scanner.getCurrentTokenString();
}
} else {
if (returnType == null) return null; // invalid syntax
switch (token) {
case TerminalTokens.TokenNameGREATER:
case TerminalTokens.TokenNameRIGHT_SHIFT:
case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
argCount--;
break;
case TerminalTokens.TokenNameLESS:
argCount++;
break;
}
returnType += scanner.getCurrentTokenString();
}
break;
}
lastToken = token;
try {
token = scanner.getNextToken();
} catch (InvalidInputException e) {
return null;
}
}
// parenthesis mismatch