/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.plugin.ij.completion.model;
import com.google.common.base.Strings;
import gw.lang.reflect.IFunctionType;
import gw.lang.reflect.IParameterInfo;
import gw.lang.reflect.IType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
public class MemberNameUtil {
public static String buildFunctionIntellisenseString(@NotNull IFunctionType functionType) {
return buildFunctionIntellisenseString(functionType, null);
}
public static String buildFunctionIntellisenseString(@NotNull IFunctionType functionType, String[] paramNames) {
final StringBuilder sb = new StringBuilder(functionType.getDisplayName());
sb.append("(");
buildArgListFromType(functionType, sb, true, paramNames);
sb.append(")");
return sb.toString();
}
private static void buildArgListFromType(@NotNull IFunctionType functionType, @NotNull StringBuilder sb, boolean topLevel, @Nullable String[] paramNames) {
IType[] parameters = functionType.getParameterTypes();
HashSet<String> generatedNames = new HashSet<>();
for (int i = 0; i < parameters.length; i++) {
if (i != 0) {
sb.append(", ");
}
IType paramType = parameters[i];
if (topLevel && paramType instanceof IFunctionType) {
IFunctionType blockType = (IFunctionType) paramType;
sb.append("\\");
buildArgListFromType(blockType, sb, false, null);
sb.append(" -> ");
} else {
// If we have a method info, we can use the actual parameter name
String name;
if (paramNames != null) {
name = paramNames[i];
} else if (functionType.getMethodInfo() != null) {
IParameterInfo info = functionType.getMethodInfo().getParameters()[i];
name = info.getName();
} else {
name = createUniqueParamNameFromType(paramType, generatedNames);
}
sb.append(uncapitalize(name));
}
}
}
static String createUniqueParamNameFromType(@NotNull IType paramType, @NotNull HashSet<String> generatedNames) {
String initialName = paramType.getRelativeName();
if (!isAlphanumeric(initialName.substring(0, 1))) {
initialName = paramType.getDisplayName();
}
String name = initialName.substring(0, 1).toLowerCase();
int j = 2;
while (generatedNames.contains(name)) {
name = initialName + j;
j++;
}
generatedNames.add(name);
return name;
}
@NotNull
public static String uncapitalize(@NotNull String str) {
return Strings.isNullOrEmpty(str) ? "" : Character.toLowerCase(str.charAt(0)) + str.substring(1);
}
public static boolean isAlphanumeric(@Nullable String str) {
if (str == null) {
return false;
}
for (int i = 0; i < str.length(); i++) {
if (!Character.isLetterOrDigit(str.charAt(i))) {
return false;
}
}
return true;
}
}