use of com.intellij.refactoring.typeMigration.TypeConversionDescriptor in project intellij-community by JetBrains.
the class GuavaFluentIterableConversionRule method getOneMethodDescriptor.
@Nullable
private static TypeConversionDescriptorBase getOneMethodDescriptor(@NotNull String methodName, @NotNull PsiMethod method, @NotNull PsiType from, @Nullable PsiType to, @Nullable PsiExpression context) {
TypeConversionDescriptor descriptorBase = null;
PsiType conversionType = null;
boolean needSpecifyType = true;
if (methodName.equals("of")) {
descriptorBase = new TypeConversionDescriptor("'FluentIterable*.of($arr$)", "java.util.Arrays.stream($arr$)");
} else if (methodName.equals("from")) {
descriptorBase = new TypeConversionDescriptor("'FluentIterable*.from($it$)", null) {
@Override
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) expression;
PsiExpression argument = PseudoLambdaReplaceTemplate.replaceTypeParameters(methodCall.getArgumentList().getExpressions()[0]);
if (argument == null) {
return expression;
}
boolean isCollection = InheritanceUtil.isInheritor(PsiTypesUtil.getPsiClass(argument.getType()), CommonClassNames.JAVA_UTIL_COLLECTION);
setReplaceByString(isCollection ? "($it$).stream()" : "java.util.stream.StreamSupport.stream(($it$).spliterator(), false)");
final PsiExpression replaced = super.replace(expression, evaluator);
ParenthesesUtils.removeParentheses(replaced, false);
return replaced;
}
};
} else if (methodName.equals("filter")) {
descriptorBase = FluentIterableConversionUtil.getFilterDescriptor(method, context);
} else if (methodName.equals("isEmpty")) {
descriptorBase = new TypeConversionDescriptor("$q$.isEmpty()", null) {
@Override
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
final PsiElement parent = expression.getParent();
boolean isDoubleNegation = false;
if (parent instanceof PsiExpression && DoubleNegationInspection.isNegation((PsiExpression) parent)) {
isDoubleNegation = true;
expression = (PsiExpression) parent.replace(expression);
}
setReplaceByString((isDoubleNegation ? "" : "!") + "$q$.findAny().isPresent()");
return super.replace(expression, evaluator);
}
};
needSpecifyType = false;
} else if (methodName.equals("transformAndConcat")) {
descriptorBase = new FluentIterableConversionUtil.TransformAndConcatConversionRule();
} else if (methodName.equals("toArray")) {
descriptorBase = FluentIterableConversionUtil.getToArrayDescriptor(from, context);
needSpecifyType = false;
} else if (methodName.equals("copyInto")) {
descriptorBase = new FluentIterableConversionUtil.CopyIntoConversionDescriptor();
needSpecifyType = false;
} else if (methodName.equals("append")) {
descriptorBase = createDescriptorForAppend(method, context);
} else if (methodName.equals("get")) {
descriptorBase = new TypeConversionDescriptor("$it$.get($p$)", null) {
@Override
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
PsiMethodCallExpression methodCall = (PsiMethodCallExpression) expression;
final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
setReplaceByString("$it$.skip($p$).findFirst().get()");
if (arguments.length == 1 && arguments[0] instanceof PsiLiteralExpression) {
final Object value = ((PsiLiteralExpression) arguments[0]).getValue();
if (value != null && value.equals(0)) {
setReplaceByString("$it$.findFirst().get()");
}
}
return super.replace(expression, evaluator);
}
};
needSpecifyType = false;
} else if (methodName.equals("contains")) {
descriptorBase = new TypeConversionDescriptor("$it$.contains($o$)", null) {
@Override
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) expression;
final PsiExpression qualifier = methodCallExpression.getMethodExpression().getQualifierExpression();
LOG.assertTrue(qualifier != null);
final PsiClassType qualifierType = (PsiClassType) qualifier.getType();
LOG.assertTrue(qualifierType != null);
final PsiType[] parameters = qualifierType.getParameters();
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expression.getProject());
final SuggestedNameInfo suggestedNameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, parameters.length == 1 ? parameters[0] : null, false);
final String suggestedName = codeStyleManager.suggestUniqueVariableName(suggestedNameInfo, expression, false).names[0];
setReplaceByString("$it$.anyMatch(" + suggestedName + " -> java.util.Objects.equals(" + suggestedName + ", $o$))");
return super.replace(expression, evaluator);
}
};
needSpecifyType = false;
} else if (methodName.equals("last")) {
descriptorBase = new TypeConversionDescriptor("$it$.last()", null) {
@Override
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expression.getProject());
String varA = suggestName("a", codeStyleManager, expression);
String varB = suggestName("b", codeStyleManager, expression);
setReplaceByString("$it$.reduce((" + varA + ", " + varB + ") -> " + varB + ")");
return super.replace(expression, evaluator);
}
private String suggestName(String baseName, JavaCodeStyleManager codeStyleManager, PsiElement place) {
final SuggestedNameInfo suggestedNameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, baseName, null, null, false);
return codeStyleManager.suggestUniqueVariableName(suggestedNameInfo, place, false).names[0];
}
};
} else {
final TypeConversionDescriptorFactory base = DESCRIPTORS_MAP.get(methodName);
if (base != null) {
final TypeConversionDescriptor descriptor = base.create();
needSpecifyType = base.isChainedMethod();
if (needSpecifyType && !base.isFluentIterableReturnType()) {
conversionType = GuavaConversionUtil.addTypeParameters(GuavaOptionalConversionRule.JAVA_OPTIONAL, context.getType(), context);
}
descriptorBase = descriptor;
}
}
if (descriptorBase == null) {
return FluentIterableConversionUtil.createToCollectionDescriptor(methodName, context);
}
if (needSpecifyType) {
if (conversionType == null) {
PsiMethodCallExpression methodCall = (PsiMethodCallExpression) (context instanceof PsiMethodCallExpression ? context : context.getParent());
conversionType = GuavaConversionUtil.addTypeParameters(GuavaTypeConversionDescriptor.isIterable(methodCall) ? CommonClassNames.JAVA_LANG_ITERABLE : StreamApiConstants.JAVA_UTIL_STREAM_STREAM, context.getType(), context);
}
descriptorBase.withConversionType(conversionType);
}
return descriptorBase;
}
use of com.intellij.refactoring.typeMigration.TypeConversionDescriptor in project intellij-community by JetBrains.
the class GuavaOptionalConversionRule method fillSimpleDescriptors.
@Override
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {
descriptorsMap.put("absent", new TypeConversionDescriptor("'Optional*.absent()", "java.util.Optional.empty()") {
@Override
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
LOG.assertTrue(expression instanceof PsiMethodCallExpression);
final PsiReferenceParameterList typeArguments = ((PsiMethodCallExpression) expression).getTypeArgumentList();
PsiReferenceParameterList typeArgumentsCopy = typeArguments.getTypeArguments().length == 0 ? null : (PsiReferenceParameterList) typeArguments.copy();
final PsiMethodCallExpression replacedExpression = (PsiMethodCallExpression) super.replace(expression, evaluator);
if (typeArgumentsCopy != null) {
replacedExpression.getTypeArgumentList().replace(typeArgumentsCopy);
}
return replacedExpression;
}
});
descriptorsMap.put("of", new TypeConversionDescriptor("'Optional*.of($ref$)", "java.util.Optional.of($ref$)"));
descriptorsMap.put("fromNullable", new TypeConversionDescriptor("'Optional*.fromNullable($ref$)", "java.util.Optional.ofNullable($ref$)"));
descriptorsMap.put("presentInstances", new TypeConversionDescriptor("'Optional*.presentInstances($it$)", "java.util.stream.StreamSupport.stream($it$.spliterator(), false).map(java.util.Optional::get).collect(java.util.Collectors.toList())"));
final TypeConversionDescriptorBase identity = new TypeConversionDescriptorBase();
descriptorsMap.put("get", identity);
descriptorsMap.put("isPresent", identity);
descriptorsMap.put("orNull", new TypeConversionDescriptor("$val$.orNull()", "$val$.orElse(null)"));
descriptorsMap.put("asSet", new TypeConversionDescriptor("$val$.asSet()", "$val$.map(java.util.Collections::singleton).orElse(java.util.Collections.emptySet())"));
}
use of com.intellij.refactoring.typeMigration.TypeConversionDescriptor in project intellij-community by JetBrains.
the class GuavaOptionalConversionRule method findConversionForMethod.
@Nullable
@Override
protected TypeConversionDescriptorBase findConversionForMethod(@Nullable PsiType from, @Nullable PsiType to, @NotNull PsiMethod method, @NotNull String methodName, PsiExpression context, TypeMigrationLabeler labeler) {
if (!(context instanceof PsiMethodCallExpression)) {
if ("or".equals(methodName)) {
PsiMethodCallExpression methodCallExpression = null;
if (context.getParent() instanceof PsiMethodCallExpression) {
methodCallExpression = (PsiMethodCallExpression) context.getParent();
}
if (methodCallExpression == null) {
return null;
}
final PsiClass aClass = getParameterClass(method);
if (aClass != null) {
final String qName = aClass.getQualifiedName();
if (GUAVA_OPTIONAL.equals(qName)) {
TypeConversionDescriptor descriptor = new TypeConversionDescriptor(null, "java.util.Optional.ofNullable($val$.orElseGet($o$::get))") {
@Override
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
setStringToReplace("$val$.or(" + GuavaOptionalConversionUtil.simplifyParameterPattern((PsiMethodCallExpression) expression) + ")");
return super.replace(expression, evaluator);
}
};
if (to != null) {
descriptor.withConversionType(to);
}
return descriptor;
}
return GuavaLambda.SUPPLIER.getClassQName().equals(qName) ? new GuavaTypeConversionDescriptor("$val$.or($other$)", "$val$.orElseGet($other$)") : new TypeConversionDescriptor("$val$.or($other$)", "$val$.orElse($other$)");
}
return null;
} else if ("transform".equals(methodName)) {
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) (context.getParent());
final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
if (arguments.length != 1) {
return null;
}
final PsiExpression functionArgument = arguments[0];
final TypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor("$val$.transform($fun$)", "$val$.map($fun$)");
final PsiType typeParameter = GuavaConversionUtil.getFunctionReturnType(functionArgument);
if (typeParameter == null) {
return descriptor;
}
final String rawOptionalType = JAVA_OPTIONAL + "<" + typeParameter.getCanonicalText(false) + ">";
return descriptor.withConversionType(JavaPsiFacade.getElementFactory(method.getProject()).createTypeFromText(rawOptionalType, context));
}
return null;
}
final PsiClass aClass = method.getContainingClass();
if (aClass == null || !(GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName()) || GUAVA_OPTIONAL.equals(aClass.getQualifiedName()))) {
return null;
}
return GuavaFluentIterableConversionRule.buildCompoundDescriptor((PsiMethodCallExpression) context, to, labeler);
}
Aggregations