mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
guava type migration: quick fix improved to work in one write-action, support guava's Predicates
This commit is contained in:
@@ -54,11 +54,11 @@ public class TypeEvaluator {
|
||||
|
||||
if (types != null) {
|
||||
for (final Pair<TypeMigrationUsageInfo, PsiType> p : types) {
|
||||
final LinkedList<PsiType> e = new LinkedList<PsiType>();
|
||||
|
||||
e.addFirst(p.getSecond());
|
||||
|
||||
myTypeMap.put(p.getFirst(), e);
|
||||
if (!(p.getFirst().getElement() instanceof PsiExpression)) {
|
||||
final LinkedList<PsiType> e = new LinkedList<PsiType>();
|
||||
e.addFirst(p.getSecond());
|
||||
myTypeMap.put(p.getFirst(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -740,7 +740,7 @@ public class TypeMigrationLabeler {
|
||||
}
|
||||
if (myException != null) throw myException;
|
||||
rememberRootTrace(usageInfo, type, place, alreadyProcessed);
|
||||
if (!alreadyProcessed && !getTypeEvaluator().setType(usageInfo, type)) {
|
||||
if (!alreadyProcessed && !(usageInfo.getElement() instanceof PsiExpression) && !getTypeEvaluator().setType(usageInfo, type)) {
|
||||
alreadyProcessed = true;
|
||||
}
|
||||
|
||||
@@ -853,6 +853,10 @@ public class TypeMigrationLabeler {
|
||||
}
|
||||
else if (root instanceof PsiVariable || root instanceof PsiExpression) {
|
||||
final PsiElement element = getContainingStatement(root);
|
||||
if (root instanceof PsiExpression) {
|
||||
migrateExpressionType((PsiExpression)root, migrationType, element, false, true);
|
||||
myTypeEvaluator.setType(newRootUsageInfo, migrationType);
|
||||
}
|
||||
element.accept(new TypeMigrationStatementProcessor(element, this));
|
||||
}
|
||||
else if (root instanceof PsiReferenceParameterList) {
|
||||
@@ -968,6 +972,7 @@ public class TypeMigrationLabeler {
|
||||
}
|
||||
|
||||
private void migrate(boolean autoMigrate, final PsiElement... victims) {
|
||||
|
||||
myMigrationRoots = new LinkedList<Pair<TypeMigrationUsageInfo, PsiType>>();
|
||||
myTypeEvaluator = new TypeEvaluator(myMigrationRoots, this);
|
||||
|
||||
|
||||
+23
-147
@@ -18,14 +18,12 @@ package com.intellij.refactoring.typeMigration.inspections;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -118,7 +116,7 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
if (targetType != null) {
|
||||
holder.registerProblem(variable.getNameIdentifier(),
|
||||
PROBLEM_DESCRIPTION_FOR_VARIABLE,
|
||||
new MigrateGuavaTypeFix(variable, targetType, null));
|
||||
new MigrateGuavaTypeFix(variable, targetType));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +130,7 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
if (typeElement != null) {
|
||||
holder.registerProblem(typeElement,
|
||||
PROBLEM_DESCRIPTION_FOR_VARIABLE,
|
||||
new MigrateGuavaTypeFix(method, targetType, null));
|
||||
new MigrateGuavaTypeFix(method, targetType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,11 +142,7 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
}
|
||||
|
||||
private void checkPredicatesUtilityMethod(PsiMethodCallExpression expression) {
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiAssignmentExpression || parent instanceof PsiVariable) {
|
||||
return;
|
||||
}
|
||||
if (FunctionalInterfaceTypeConversionDescriptor.isPredicates(expression)) {
|
||||
if (GuavaPredicateConversionRule.isPredicates(expression)) {
|
||||
final PsiMethod method = expression.resolveMethod();
|
||||
if (GuavaPredicateConversionRule.isConvertablePredicatesMethod(method)) {
|
||||
final PsiClassType initialType = (PsiClassType)expression.getType();
|
||||
@@ -156,7 +150,7 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
if (targetType == null) return;
|
||||
holder.registerProblem(expression.getMethodExpression().getReferenceNameElement(),
|
||||
PROBLEM_DESCRIPTION_FOR_VARIABLE,
|
||||
new MigrateGuavaTypeFix(expression, targetType, initialType));
|
||||
new MigrateGuavaTypeFix(expression, targetType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,21 +164,16 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiElement maybeLocalVariable = chain.getParent();
|
||||
if (maybeLocalVariable instanceof PsiLocalVariable) {
|
||||
final PsiClass aClass = PsiUtil.resolveClassInType(((PsiLocalVariable)maybeLocalVariable).getType());
|
||||
if (aClass != null && (GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName()) ||
|
||||
GuavaOptionalConversionRule.GUAVA_OPTIONAL.equals(aClass.getQualifiedName()))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PsiClassType initialType = (PsiClassType)expression.getType();
|
||||
PsiClassType initialType = (PsiClassType)chain.getType();
|
||||
LOG.assertTrue(initialType != null);
|
||||
PsiClassType targetType = createTargetType(initialType);
|
||||
if (targetType == null) return;
|
||||
|
||||
holder.registerProblem(chain, PROBLEM_DESCRIPTION_FOR_METHOD_CHAIN, new MigrateGuavaTypeFix(chain, targetType, initialType));
|
||||
PsiElement highlightedElement = chain;
|
||||
if (chain.getParent() instanceof PsiReferenceExpression && chain.getParent().getParent() instanceof PsiMethodCallExpression) {
|
||||
highlightedElement = chain.getParent().getParent();
|
||||
}
|
||||
holder.registerProblem(highlightedElement, PROBLEM_DESCRIPTION_FOR_METHOD_CHAIN, new MigrateGuavaTypeFix(chain, targetType));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -252,6 +241,15 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
|| GuavaOptionalConversionRule.GUAVA_OPTIONAL.equals(containingClass.getQualifiedName()))) {
|
||||
return chain;
|
||||
}
|
||||
final PsiType returnType = method.getReturnType();
|
||||
final PsiClass returnClass = PsiTypesUtil.getPsiClass(returnType);
|
||||
if (returnClass == null || !(GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(returnClass.getQualifiedName())
|
||||
|| GuavaOptionalConversionRule.GUAVA_OPTIONAL.equals(returnClass.getQualifiedName()))) {
|
||||
return chain;
|
||||
}
|
||||
if (GuavaTypeConversionDescriptor.isIterable(current)) {
|
||||
return chain;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return chain;
|
||||
@@ -283,14 +281,11 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
}
|
||||
|
||||
public static class MigrateGuavaTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement implements BatchQuickFix<ProblemDescriptor> {
|
||||
@Nullable
|
||||
private final PsiType myInitialType;
|
||||
private final PsiType myTargetType;
|
||||
|
||||
private MigrateGuavaTypeFix(@NotNull PsiElement element, PsiType targetType, @Nullable PsiType initialType) {
|
||||
private MigrateGuavaTypeFix(@NotNull PsiElement element, PsiType targetType) {
|
||||
super(element);
|
||||
myTargetType = targetType;
|
||||
myInitialType = initialType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -299,11 +294,7 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
@Nullable("is null when called from inspection") Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
if (myInitialType == null) {
|
||||
performTypeMigration(Collections.singletonList(startElement), Collections.singletonList(myTargetType));
|
||||
} else {
|
||||
performMethodCallTypeMigration(project, Collections.singletonList(new ChainFixInfo(startElement, myInitialType, myTargetType)));
|
||||
}
|
||||
performTypeMigration(Collections.singletonList(startElement), Collections.singletonList(myTargetType));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -342,118 +333,15 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
final List<PsiElement> elementsToFix = new ArrayList<PsiElement>();
|
||||
final List<PsiType> migrationTypes = new ArrayList<PsiType>();
|
||||
|
||||
final List<ChainFixInfo> chainFixInfos = new ArrayList<ChainFixInfo>();
|
||||
|
||||
for (ProblemDescriptor descriptor : descriptors) {
|
||||
final MigrateGuavaTypeFix fix = getFix(descriptor);
|
||||
if (fix.myInitialType == null) {
|
||||
elementsToFix.add(fix.getStartElement());
|
||||
migrationTypes.add(fix.myTargetType);
|
||||
}
|
||||
else {
|
||||
chainFixInfos.add(new ChainFixInfo(fix.getStartElement(), fix.myInitialType, fix.myTargetType));
|
||||
}
|
||||
elementsToFix.add(fix.getStartElement());
|
||||
migrationTypes.add(fix.myTargetType);
|
||||
}
|
||||
|
||||
if (!chainFixInfos.isEmpty()) performMethodCallTypeMigration(project, chainFixInfos);
|
||||
if (!elementsToFix.isEmpty()) performTypeMigration(elementsToFix, migrationTypes);
|
||||
}
|
||||
|
||||
private static void performMethodCallTypeMigration(@NotNull final Project project,
|
||||
final List<ChainFixInfo> elements) {
|
||||
Collections.sort(elements, new Comparator<ChainFixInfo>() {
|
||||
@Override
|
||||
public int compare(ChainFixInfo o1, ChainFixInfo o2) {
|
||||
final PsiElement element1 = o1.myElement;
|
||||
final PsiElement element2 = o2.myElement;
|
||||
if (element1.getTextRange().contains(element2.getTextRange())) {
|
||||
return 1;
|
||||
}
|
||||
if (element2.getTextRange().contains(element1.getTextRange())) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
final List<PsiElement> validElement = new ArrayList<PsiElement>();
|
||||
final List<Boolean> isIterableList = new ArrayList<Boolean>(elements.size());
|
||||
final List<TypeConversionDescriptorBase> conversionList = new ArrayList<TypeConversionDescriptorBase>(elements.size());
|
||||
|
||||
for (ChainFixInfo info : elements) {
|
||||
final PsiElement element = info.myElement;
|
||||
final PsiType initialType = info.myFrom;
|
||||
final PsiType targetType = info.myTo;
|
||||
if (element.isValid()) {
|
||||
PsiMethodCallExpression expr = (PsiMethodCallExpression)element;
|
||||
final TypeMigrationRules rules = new TypeMigrationRules();
|
||||
rules.setBoundScope(element.getUseScope());
|
||||
conversionList.add(rules.findConversion(initialType, targetType, expr.resolveMethod(), expr, new TypeMigrationLabeler(rules, targetType)));
|
||||
isIterableList.add(isIterable(expr));
|
||||
validElement.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
if (!validElement.isEmpty()) {
|
||||
final PsiFile file = validElement.get(0).getContainingFile();
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Iterator<Boolean> isIterableIterator = isIterableList.iterator();
|
||||
final Iterator<TypeConversionDescriptorBase> conversionIterator = conversionList.iterator();
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
for (PsiElement element : validElement) {
|
||||
PsiElement replacedExpression = TypeMigrationReplacementUtil.replaceExpression((PsiExpression)element,
|
||||
project,
|
||||
conversionIterator.next(),
|
||||
new TypeEvaluator(null, null));
|
||||
if (isIterableIterator.next()) {
|
||||
final String expressionText = replacedExpression.getText() + ".collect(java.util.stream.Collectors.toList())";
|
||||
replacedExpression = replacedExpression
|
||||
.replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(expressionText, replacedExpression));
|
||||
}
|
||||
codeStyleManager.shortenClassReferences(replacedExpression);
|
||||
}
|
||||
codeStyleManager.optimizeImports(file);
|
||||
UndoUtil.markPsiFileForUndo(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isIterable(PsiMethodCallExpression expression) {
|
||||
final PsiElement parent = expression.getParent();
|
||||
final PsiMethod method = expression.resolveMethod();
|
||||
if (method != null) {
|
||||
final PsiClass returnClass = PsiTypesUtil.getPsiClass(method.getReturnType());
|
||||
if (returnClass == null || !GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(returnClass.getQualifiedName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (parent instanceof PsiLocalVariable) {
|
||||
return isIterable(((PsiLocalVariable)parent).getType());
|
||||
}
|
||||
else if (parent instanceof PsiReturnStatement) {
|
||||
final PsiElement methodOrLambda = PsiTreeUtil.getParentOfType(parent, PsiMethod.class, PsiLambdaExpression.class);
|
||||
PsiType methodReturnType = null;
|
||||
if (methodOrLambda instanceof PsiMethod) {
|
||||
methodReturnType = ((PsiMethod)methodOrLambda).getReturnType();
|
||||
}
|
||||
else if (methodOrLambda instanceof PsiLambdaExpression) {
|
||||
methodReturnType = LambdaUtil.getFunctionalInterfaceReturnType((PsiFunctionalExpression)methodOrLambda);
|
||||
}
|
||||
return isIterable(methodReturnType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isIterable(@Nullable PsiType type) {
|
||||
PsiClass aClass;
|
||||
return (aClass = PsiTypesUtil.getPsiClass(type)) != null && CommonClassNames.JAVA_LANG_ITERABLE.equals(aClass.getQualifiedName());
|
||||
}
|
||||
|
||||
private static MigrateGuavaTypeFix getFix(ProblemDescriptor descriptor) {
|
||||
final QuickFix[] fixes = descriptor.getFixes();
|
||||
LOG.assertTrue(fixes != null);
|
||||
@@ -513,17 +401,5 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class ChainFixInfo {
|
||||
private final PsiElement myElement;
|
||||
private final PsiType myFrom;
|
||||
private final PsiType myTo;
|
||||
|
||||
private ChainFixInfo(PsiElement element, PsiType from, PsiType to) {
|
||||
myElement = element;
|
||||
myFrom = from;
|
||||
myTo = to;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -122,12 +122,12 @@ public class FluentIterableConversionUtil {
|
||||
return new GuavaFilterInstanceOfConversionDescriptor();
|
||||
}
|
||||
else if (GuavaPredicateConversionRule.GUAVA_PREDICATE.equals(resolvedClass.getQualifiedName())) {
|
||||
return new LambdaParametersTypeConversionDescriptor("$it$.filter($p$)", "$it$." + StreamApiConstants.FILTER + "($p$)");
|
||||
return new GuavaTypeConversionDescriptor("$it$.filter($p$)", "$it$." + StreamApiConstants.FILTER + "($p$)");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static class TransformAndConcatConversionRule extends LambdaParametersTypeConversionDescriptor {
|
||||
static class TransformAndConcatConversionRule extends GuavaTypeConversionDescriptor {
|
||||
public TransformAndConcatConversionRule() {
|
||||
super("$q$.transformAndConcat($params$)", "$q$.flatMap($params$)");
|
||||
}
|
||||
@@ -248,8 +248,8 @@ public class FluentIterableConversionUtil {
|
||||
final String replaceTemplate;
|
||||
final String returnType;
|
||||
if ("toMap".equals(methodName) || "uniqueIndex".equals(methodName)) {
|
||||
final LambdaParametersTypeConversionDescriptor descriptor = new LambdaParametersTypeConversionDescriptor("$it$.$methodName$($f$)",
|
||||
"$it$.collect(java.util.stream.Collectors.toMap(java.util.function.Function.identity(), $f$))");
|
||||
final GuavaTypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor("$it$.$methodName$($f$)",
|
||||
"$it$.collect(java.util.stream.Collectors.toMap(java.util.function.Function.identity(), $f$))");
|
||||
return descriptor.withConversionType(GuavaConversionUtil.addTypeParameters(CommonClassNames.JAVA_UTIL_MAP, context.getType(), context));
|
||||
}
|
||||
else if ("toList".equals(methodName)) {
|
||||
|
||||
+32
-28
@@ -16,8 +16,10 @@
|
||||
package com.intellij.refactoring.typeMigration.rules.guava;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
|
||||
import com.intellij.refactoring.typeMigration.TypeEvaluator;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -26,11 +28,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class FunctionalInterfaceTypeConversionDescriptor extends TypeConversionDescriptor {
|
||||
@NotNull private final String myMethodName;
|
||||
@NotNull private final String myTargetMethodName;
|
||||
@NotNull private final String myTargetClassQName;
|
||||
|
||||
FunctionalInterfaceTypeConversionDescriptor(@NotNull String methodName, @NotNull String targetMethodName) {
|
||||
FunctionalInterfaceTypeConversionDescriptor(@NotNull String methodName,
|
||||
@NotNull String targetMethodName,
|
||||
@NotNull String targetClassQName) {
|
||||
super(null, null);
|
||||
myMethodName = methodName;
|
||||
myTargetMethodName = targetMethodName;
|
||||
myTargetClassQName = targetClassQName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,49 +45,47 @@ public class FunctionalInterfaceTypeConversionDescriptor extends TypeConversionD
|
||||
expression = (PsiExpression)expression.getParent();
|
||||
}
|
||||
if (expression instanceof PsiMethodReferenceExpression) {
|
||||
setAsMethodReference((PsiMethodReferenceExpression)expression);
|
||||
expression = setupAsMethodReference(expression);
|
||||
}
|
||||
else if (expression instanceof PsiReferenceExpression) {
|
||||
setAsReference();
|
||||
setupAsReference();
|
||||
}
|
||||
else {
|
||||
setAsMethodCall();
|
||||
setupAsMethodCall();
|
||||
}
|
||||
return super.replace(expression, evaluator);
|
||||
final PsiExpression converted = super.replace(expression, evaluator);
|
||||
final PsiElement parent = converted.getParent();
|
||||
if (parent instanceof PsiParenthesizedExpression) {
|
||||
if (!ParenthesesUtils.areParenthesesNeeded((PsiParenthesizedExpression)parent, true)) {
|
||||
return (PsiExpression)parent.replace(converted);
|
||||
}
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
private void setAsReference() {
|
||||
private void setupAsReference() {
|
||||
setStringToReplace("$ref$");
|
||||
setReplaceByString("$ref$::" + myTargetMethodName);
|
||||
}
|
||||
|
||||
private void setAsMethodReference(PsiMethodReferenceExpression methodReference) {
|
||||
setStringToReplace("$qualifier$::" + myMethodName);
|
||||
if (methodReference.getParent() instanceof PsiExpressionList &&
|
||||
methodReference.getParent().getParent() instanceof PsiMethodCallExpression &&
|
||||
isPredicates((PsiMethodCallExpression)methodReference.getParent().getParent())) {
|
||||
setReplaceByString("$qualifier$::" + myTargetMethodName);
|
||||
return;
|
||||
private PsiExpression setupAsMethodReference(PsiExpression methodReferenceExpression) {
|
||||
final PsiElement parent = methodReferenceExpression.getParent();
|
||||
if (parent instanceof PsiTypeCastExpression) {
|
||||
final PsiTypeElement typeElement = ((PsiTypeCastExpression)parent).getCastType();
|
||||
if (typeElement != null) {
|
||||
final PsiClass resolvedClass = PsiTypesUtil.getPsiClass(typeElement.getType());
|
||||
if (resolvedClass != null && myTargetClassQName.equals(resolvedClass.getQualifiedName())) {
|
||||
methodReferenceExpression = (PsiExpression)parent.replace(methodReferenceExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
setStringToReplace("$qualifier$::" + myMethodName);
|
||||
setReplaceByString("$qualifier$");
|
||||
return methodReferenceExpression;
|
||||
}
|
||||
|
||||
private void setAsMethodCall() {
|
||||
private void setupAsMethodCall() {
|
||||
setStringToReplace("$qualifier$." + myMethodName + "($param$)");
|
||||
setReplaceByString("$qualifier$." + myTargetMethodName + "($param$)");
|
||||
}
|
||||
|
||||
public static boolean isPredicates(PsiMethodCallExpression expression) {
|
||||
final String methodName = expression.getMethodExpression().getReferenceName();
|
||||
if (GuavaPredicateConversionRule.PREDICATES_NOT.equals(methodName) ||
|
||||
GuavaPredicateConversionRule.PREDICATES_AND_OR.contains(methodName)) {
|
||||
final PsiMethod method = expression.resolveMethod();
|
||||
if (method == null) return false;
|
||||
final PsiClass aClass = method.getContainingClass();
|
||||
if (aClass != null && GuavaPredicateConversionRule.GUAVA_PREDICATES_UTILITY.equals(aClass.getQualifiedName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -77,8 +77,11 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
|
||||
}
|
||||
|
||||
public TypeConversionDescriptor create() {
|
||||
return myWithLambdaParameter ? new LambdaParametersTypeConversionDescriptor(myStringToReplace, myReplaceByString)
|
||||
: new TypeConversionDescriptor(myStringToReplace, myReplaceByString);
|
||||
GuavaTypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor(myStringToReplace, myReplaceByString);
|
||||
if (!myWithLambdaParameter) {
|
||||
descriptor = descriptor.setConvertParameterAsLambda(false);
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public boolean isChainedMethod() {
|
||||
@@ -225,7 +228,8 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
|
||||
if (descriptorBase != null) {
|
||||
if (needSpecifyType) {
|
||||
if (conversionType == null) {
|
||||
conversionType = GuavaConversionUtil.addTypeParameters(StreamApiConstants.JAVA_UTIL_STREAM_STREAM, context.getType(), context);
|
||||
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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -34,14 +34,14 @@ public class GuavaFunctionConversionRule extends BaseGuavaTypeConversionRule {
|
||||
|
||||
@Override
|
||||
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {
|
||||
descriptorsMap.put("apply", new FunctionalInterfaceTypeConversionDescriptor("apply", "apply"));
|
||||
descriptorsMap.put("apply", new FunctionalInterfaceTypeConversionDescriptor("apply", "apply", JAVA_UTIL_FUNCTION_FUNCTION));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression,
|
||||
@NotNull PsiVariable psiVariable, PsiExpression context) {
|
||||
return new FunctionalInterfaceTypeConversionDescriptor("apply", "apply");
|
||||
return new FunctionalInterfaceTypeConversionDescriptor("apply", "apply", JAVA_UTIL_FUNCTION_FUNCTION);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+2
-2
@@ -74,7 +74,7 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
|
||||
return descriptor;
|
||||
}
|
||||
return GuavaSupplierConversionRule.GUAVA_SUPPLIER.equals(qName)
|
||||
? new LambdaParametersTypeConversionDescriptor("$val$.or($other$)", "$val$.orElseGet($other$)")
|
||||
? new GuavaTypeConversionDescriptor("$val$.or($other$)", "$val$.orElseGet($other$)")
|
||||
: new TypeConversionDescriptor("$val$.or($other$)", "$val$.orElse($other$)");
|
||||
}
|
||||
return null;
|
||||
@@ -86,7 +86,7 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
|
||||
return null;
|
||||
}
|
||||
final PsiExpression functionArgument = arguments[0];
|
||||
final TypeConversionDescriptor descriptor = new LambdaParametersTypeConversionDescriptor("$val$.transform($fun$)", "$val$.map($fun$)");
|
||||
final TypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor("$val$.transform($fun$)", "$val$.map($fun$)");
|
||||
final PsiType typeParameter = GuavaConversionUtil.getFunctionReturnType(functionArgument);
|
||||
if (typeParameter == null) {
|
||||
return descriptor;
|
||||
|
||||
+72
-2
@@ -17,6 +17,7 @@ package com.intellij.refactoring.typeMigration.rules.guava;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.RedundantCastUtil;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
|
||||
@@ -54,14 +55,14 @@ public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule {
|
||||
|
||||
@Override
|
||||
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {
|
||||
descriptorsMap.put("apply", new FunctionalInterfaceTypeConversionDescriptor("apply", "test"));
|
||||
descriptorsMap.put("apply", new FunctionalInterfaceTypeConversionDescriptor("apply", "test", JAVA_PREDICATE));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression,
|
||||
@NotNull PsiVariable psiVariable, PsiExpression context) {
|
||||
return new FunctionalInterfaceTypeConversionDescriptor("apply", "test");
|
||||
return new FunctionalInterfaceTypeConversionDescriptor("apply", "test", JAVA_PREDICATE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -127,6 +128,14 @@ public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule {
|
||||
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException {
|
||||
String newExpressionString =
|
||||
adjust(((PsiMethodCallExpression)expression).getArgumentList().getExpressions()[0], true, myTargetType, evaluator) + ".negate()";
|
||||
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiMethodReferenceExpression) {
|
||||
expression = replaceTypeCast(expression, parent);
|
||||
}
|
||||
else if (!isJavaPredicate(parent, evaluator)) {
|
||||
newExpressionString += "::test";
|
||||
}
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject());
|
||||
PsiExpression convertedExpression =
|
||||
(PsiExpression)expression.replace(elementFactory.createExpressionFromText(newExpressionString, expression));
|
||||
@@ -165,9 +174,56 @@ public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule {
|
||||
replaceBy.append(".").append(methodName).append("(").append(adjust(argument, false, myTargetType, evaluator)).append(")");
|
||||
}
|
||||
replaceBy.insert(0, adjust(arguments[0], true, myTargetType, evaluator));
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiMethodReferenceExpression) {
|
||||
expression = replaceTypeCast(expression, parent);
|
||||
}
|
||||
else if (!isJavaPredicate(parent, evaluator)) {
|
||||
replaceBy.append("::test");
|
||||
}
|
||||
return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(replaceBy.toString(), expression));
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiExpression replaceTypeCast(PsiExpression expression, PsiElement parent) {
|
||||
final PsiElement parParent = parent.getParent();
|
||||
if (parParent instanceof PsiTypeCastExpression) {
|
||||
final PsiTypeElement typeElement = ((PsiTypeCastExpression)parParent).getCastType();
|
||||
if (typeElement != null) {
|
||||
final PsiType type = typeElement.getType();
|
||||
final PsiClass aClass = PsiTypesUtil.getPsiClass(type);
|
||||
if (aClass != null && JAVA_PREDICATE.equals(aClass.getQualifiedName())) {
|
||||
expression = (PsiExpression)parParent.replace(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
public static boolean isJavaPredicate(PsiElement element, TypeEvaluator evaluator) {
|
||||
if (element instanceof PsiLocalVariable) {
|
||||
return isJavaPredicate(evaluator.getType(element));
|
||||
}
|
||||
else if (element instanceof PsiReturnStatement) {
|
||||
final PsiElement methodOrLambda = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiLambdaExpression.class);
|
||||
PsiType methodReturnType = null;
|
||||
if (methodOrLambda instanceof PsiMethod) {
|
||||
methodReturnType = evaluator.getType(methodOrLambda);
|
||||
}
|
||||
return isJavaPredicate(methodReturnType);
|
||||
}
|
||||
else if (element instanceof PsiExpressionList) {
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
return evaluator.getType(parent) != null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isJavaPredicate(@Nullable PsiType type) {
|
||||
PsiClass aClass;
|
||||
return (aClass = PsiTypesUtil.getPsiClass(type)) != null && JAVA_PREDICATE.equals(aClass.getQualifiedName());
|
||||
}
|
||||
|
||||
private static boolean isUnconverted(PsiType type) {
|
||||
@@ -212,4 +268,18 @@ public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule {
|
||||
public String ruleToClass() {
|
||||
return JAVA_PREDICATE;
|
||||
}
|
||||
|
||||
public static boolean isPredicates(PsiMethodCallExpression expression) {
|
||||
final String methodName = expression.getMethodExpression().getReferenceName();
|
||||
if (PREDICATES_NOT.equals(methodName) ||
|
||||
PREDICATES_AND_OR.contains(methodName)) {
|
||||
final PsiMethod method = expression.resolveMethod();
|
||||
if (method == null) return false;
|
||||
final PsiClass aClass = method.getContainingClass();
|
||||
if (aClass != null && GUAVA_PREDICATES_UTILITY.equals(aClass.getQualifiedName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -34,14 +34,14 @@ public class GuavaSupplierConversionRule extends BaseGuavaTypeConversionRule {
|
||||
|
||||
@Override
|
||||
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {
|
||||
descriptorsMap.put("get", new FunctionalInterfaceTypeConversionDescriptor("get", "get"));
|
||||
descriptorsMap.put("get", new FunctionalInterfaceTypeConversionDescriptor("get", "get", JAVA_SUPPLIER));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression,
|
||||
@NotNull PsiVariable psiVariable, PsiExpression context) {
|
||||
return new FunctionalInterfaceTypeConversionDescriptor("get", "get");
|
||||
return new FunctionalInterfaceTypeConversionDescriptor("get", "get", JAVA_SUPPLIER);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+44
-8
@@ -21,31 +21,43 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
|
||||
import com.intellij.refactoring.typeMigration.TypeEvaluator;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
class LambdaParametersTypeConversionDescriptor extends TypeConversionDescriptor {
|
||||
private static final Logger LOG = Logger.getInstance(LambdaParametersTypeConversionDescriptor.class);
|
||||
public class GuavaTypeConversionDescriptor extends TypeConversionDescriptor {
|
||||
private static final Logger LOG = Logger.getInstance(GuavaTypeConversionDescriptor.class);
|
||||
private final String myReplaceByStringSource;
|
||||
private boolean myConvertParameterAsLambda = true;
|
||||
|
||||
LambdaParametersTypeConversionDescriptor(@NonNls String stringToReplace, @NonNls String replaceByString) {
|
||||
GuavaTypeConversionDescriptor(@NonNls String stringToReplace, @NonNls String replaceByString) {
|
||||
super(stringToReplace, replaceByString);
|
||||
myReplaceByStringSource = replaceByString;
|
||||
}
|
||||
|
||||
public GuavaTypeConversionDescriptor setConvertParameterAsLambda(boolean convertParameterAsLambda) {
|
||||
myConvertParameterAsLambda = convertParameterAsLambda;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiExpression replace(PsiExpression expression, TypeEvaluator evaluator) throws IncorrectOperationException {
|
||||
LOG.assertTrue(expression instanceof PsiMethodCallExpression);
|
||||
LOG.assertTrue(expression instanceof PsiMethodCallExpression);
|
||||
PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression;
|
||||
final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
|
||||
if (arguments.length == 1) {
|
||||
final PsiExpression functionArg = arguments[0];
|
||||
customizeParameter(convertParameter(functionArg, evaluator));
|
||||
setReplaceByString(myReplaceByStringSource + (isIterable(methodCall) ? ".collect(java.util.stream.Collectors.toList())" : ""));
|
||||
if (myConvertParameterAsLambda) {
|
||||
final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
|
||||
if (arguments.length == 1) {
|
||||
final PsiExpression functionArg = arguments[0];
|
||||
customizeParameter(convertParameter(functionArg, evaluator));
|
||||
}
|
||||
}
|
||||
return super.replace(expression, evaluator);
|
||||
}
|
||||
@@ -107,4 +119,28 @@ class LambdaParametersTypeConversionDescriptor extends TypeConversionDescriptor
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
public static boolean isIterable(PsiMethodCallExpression expression) {
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiLocalVariable) {
|
||||
return isIterable(((PsiLocalVariable)parent).getType());
|
||||
}
|
||||
else if (parent instanceof PsiReturnStatement) {
|
||||
final PsiElement methodOrLambda = PsiTreeUtil.getParentOfType(parent, PsiMethod.class, PsiLambdaExpression.class);
|
||||
PsiType methodReturnType = null;
|
||||
if (methodOrLambda instanceof PsiMethod) {
|
||||
methodReturnType = ((PsiMethod)methodOrLambda).getReturnType();
|
||||
}
|
||||
else if (methodOrLambda instanceof PsiLambdaExpression) {
|
||||
methodReturnType = LambdaUtil.getFunctionalInterfaceReturnType((PsiFunctionalExpression)methodOrLambda);
|
||||
}
|
||||
return isIterable(methodReturnType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isIterable(@Nullable PsiType type) {
|
||||
PsiClass aClass;
|
||||
return (aClass = PsiTypesUtil.getPsiClass(type)) != null && CommonClassNames.JAVA_LANG_ITERABLE.equals(aClass.getQualifiedName());
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -79,7 +79,7 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase {
|
||||
}
|
||||
|
||||
public void testFluentIterableChainWithoutVariable() {
|
||||
doTest();
|
||||
doTestAllFile();;
|
||||
}
|
||||
|
||||
public void testChainedFluentIterableWithChainedInitializer() {
|
||||
@@ -114,10 +114,6 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDontShowFluentIterableChainQuickFix() {
|
||||
doTestNoQuickFixes(PsiMethodCallExpression.class);
|
||||
}
|
||||
|
||||
public void testRemoveMethodReferenceForFunctionalInterfaces() {
|
||||
doTest();
|
||||
}
|
||||
@@ -257,6 +253,10 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase {
|
||||
doTestAllFile();
|
||||
}
|
||||
|
||||
public void testPredicates3() {
|
||||
doTestAllFile();
|
||||
}
|
||||
|
||||
private void doTestNoQuickFixes(Class<? extends PsiElement>... highlightedElements) {
|
||||
myFixture.configureByFile(getTestName(true) + ".java");
|
||||
myFixture.enableInspections(new GuavaInspection());
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class A {
|
||||
void c() {
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
FluentIterable<String> it = FluentIte<caret>rable.from(strings).transform(String::trim);
|
||||
System.out.println(it.size());
|
||||
}
|
||||
}
|
||||
+21
-21
@@ -1,25 +1,25 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.util.*;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
class A {
|
||||
int m1() {
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
int size = FluentIterable.fro<caret>m(strings).transform(s -> s + s).limit(10).size();
|
||||
return size
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
class Main {
|
||||
void mmm() {
|
||||
Iterator<String> iterator = m().iterator();
|
||||
int i = m1() + 10;
|
||||
FluentIterable<String> strings = m2();
|
||||
}
|
||||
|
||||
Iterable<String> m() {
|
||||
return FluentIterable.from(new ArrayList<String>()).transform(s -> s + s).filter(String::isEmpty);
|
||||
}
|
||||
|
||||
int m1() {
|
||||
return FluentIterable.from(new ArrayList<String>()).transform(s -> s + s).size();
|
||||
}
|
||||
|
||||
FluentIterable<String> m2() {
|
||||
return FluentIterable.from(new ArrayList<String>()).transform(s -> s + s).filter(String::isEmpty);
|
||||
}
|
||||
|
||||
}
|
||||
+21
-21
@@ -1,25 +1,25 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
int m1() {
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
int size = (int) strings.stream().map(s -> s + s).limit(10).count();
|
||||
return size
|
||||
class Main {
|
||||
void mmm() {
|
||||
Iterator<String> iterator = m().iterator();
|
||||
int i = m1() + 10;
|
||||
Stream<String> strings = m2();
|
||||
}
|
||||
|
||||
Iterable<String> m() {
|
||||
return new ArrayList<String>().stream().map(s -> s + s).filter(String::isEmpty).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
int m1() {
|
||||
return (int) new ArrayList<String>().stream().map(s -> s + s).count();
|
||||
}
|
||||
|
||||
Stream<String> m2() {
|
||||
return new ArrayList<String>().stream().map(s -> s + s).filter(String::isEmpty);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class Main {
|
||||
|
||||
Predicate<String> not1 = p1.negate();
|
||||
|
||||
Predicate<String> not2 = ((Predicate<String>) p1).or(((Predicate<String>) p1).or(p2)).negate();
|
||||
Predicate<String> not2 = p1.or(p1.or(p2)).negate();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Main {
|
||||
|
||||
void m(Predicate<String> p1, Predicate<String> p2) {
|
||||
Predicate<String> p = Predicates.and(p1, p2);
|
||||
}
|
||||
|
||||
Predicate<String> m123(Predicate<String> p1, Predicate<String> p2) {
|
||||
return Predicates.and(p1, p2);
|
||||
}
|
||||
|
||||
void ml(Predicate<String> p1, Predicate<String> p2) {
|
||||
Predicate<String> p = Predicates.and(p1, Predicates.not(p2));
|
||||
}
|
||||
|
||||
void mll(Predicate<String> p1, Predicate<String> p2) {
|
||||
Predicate<String> p = Predicates.and(p1, Predicates.not(Predicates.or(p2, p1)));
|
||||
}
|
||||
|
||||
void mlll(Predicate<String> p1, Predicate<String> p2) {
|
||||
FluentIterable<String> fi = FluentIterable.from(new ArrayList<>());
|
||||
Iterable<String> ooooooo = fi.filter(Predicates.and(p1, Predicates.not(Predicates.or(p1, p2))));
|
||||
Iterable<String> ooooooo1 = fi.filter(p2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class Main {
|
||||
|
||||
void m(Predicate<String> p1, Predicate<String> p2) {
|
||||
Predicate<String> p = p1.and(p2);
|
||||
}
|
||||
|
||||
Predicate<String> m123(Predicate<String> p1, Predicate<String> p2) {
|
||||
return p1.and(p2);
|
||||
}
|
||||
|
||||
void ml(Predicate<String> p1, Predicate<String> p2) {
|
||||
Predicate<String> p = p1.and(p2.negate());
|
||||
}
|
||||
|
||||
void mll(Predicate<String> p1, Predicate<String> p2) {
|
||||
Predicate<String> p = p1.and(p2.or(p1).negate());
|
||||
}
|
||||
|
||||
void mlll(Predicate<String> p1, Predicate<String> p2) {
|
||||
Stream<String> fi = new ArrayList<String>().stream();
|
||||
Iterable<String> ooooooo = fi.filter(p1.and(p1.or(p2).negate())).collect(Collectors.toList());
|
||||
Iterable<String> ooooooo1 = fi.filter(p2).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user