From 2012f8af93d48fa0fa72b84038cae5e64d04ad57 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 24 Jul 2017 11:50:39 +0700 Subject: [PATCH] StreamApiUtil split and moved to java-analysis-impl module Refactoring-related methods moved from StreamApiUtil to StreamRefactoringUtil --- .../intention/impl/StreamRefactoringUtil.java | 102 ++++++++++- ...SimplifyStreamApiCallChainsInspection.java | 3 +- .../streamMigration/CollectMigration.java | 5 +- .../StreamApiMigrationInspection.java | 3 +- .../codeInspection/util/OptionalUtil.java | 5 +- .../CollectionChainCallExtractor.java | 5 +- .../chainCall/StreamChainCallExtractor.java | 11 +- .../com/siyeh/ig/psiutils/StreamApiUtil.java | 83 +++++++++ .../com/siyeh/ig/psiutils/StreamApiUtil.java | 171 ------------------ 9 files changed, 200 insertions(+), 188 deletions(-) create mode 100644 plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/StreamApiUtil.java delete mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/StreamApiUtil.java diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/StreamRefactoringUtil.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/StreamRefactoringUtil.java index 767793a11351..e67b4e0a6412 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/StreamRefactoringUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/StreamRefactoringUtil.java @@ -15,11 +15,16 @@ */ package com.intellij.codeInsight.intention.impl; -import com.intellij.psi.LambdaUtil; -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiLambdaExpression; -import com.intellij.psi.PsiMethodReferenceExpression; +import com.intellij.codeInspection.util.OptionalUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.util.LambdaRefactoringUtil; +import com.intellij.refactoring.util.RefactoringUtil; +import com.siyeh.ig.psiutils.ExpressionUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; /** * @author Tagir Valeev @@ -35,4 +40,93 @@ public class StreamRefactoringUtil { } return false; } + + @NotNull + public static String generateMapOperation(PsiVariable variable, @Nullable PsiType outType, PsiElement mapper) { + String shortcutMappingMethod = getShortcutMappingMethod(variable, outType, mapper); + if (shortcutMappingMethod != null) return shortcutMappingMethod.isEmpty() ? "" : "." + shortcutMappingMethod + "()"; + PsiType inType = variable.getType(); + String operationName = getMapOperationName(inType, outType); + if(outType != null && mapper instanceof PsiArrayInitializerExpression) { + mapper = RefactoringUtil.convertInitializerToNormalExpression((PsiExpression)mapper, outType); + } + String typeArgument = mapper instanceof PsiExpression ? OptionalUtil.getMapTypeArgument((PsiExpression)mapper, outType) : ""; + return "." + typeArgument + operationName + + "(" + variable.getName() + "->" + mapper.getText() + ")"; + } + + /** + * Returns the shortcut mapping method name + * + * @param variable mapper input variable + * @param outType output type of the mapper + * @param mapper mapper code + * @return shortcut mapping name ("boxed", "asLongStream", "asDoubleStream") if applicable, empty string if it's + * ditto mapping (no mapping is necessary at all) and null if no shortcut is applicable for given mapper + */ + @Nullable + public static String getShortcutMappingMethod(PsiVariable variable, @Nullable PsiType outType, PsiElement mapper) { + if (!(mapper instanceof PsiExpression)) return null; + PsiExpression expression = PsiUtil.skipParenthesizedExprDown(((PsiExpression)mapper)); + PsiType inType = variable.getType(); + if (expression instanceof PsiTypeCastExpression && inType instanceof PsiPrimitiveType && Objects.equals(expression.getType(), outType)) { + expression = ((PsiTypeCastExpression)expression).getOperand(); + } + if (ExpressionUtils.isReferenceTo(expression, variable)) { + if (!(outType instanceof PsiPrimitiveType)) { + return inType instanceof PsiPrimitiveType ? "boxed" : ""; + } + if (outType.equals(inType)) { + return ""; + } + if (PsiType.LONG.equals(outType) && PsiType.INT.equals(inType)) { + return "asLongStream"; + } + if (PsiType.DOUBLE.equals(outType) && (PsiType.LONG.equals(inType) || PsiType.INT.equals(inType))) { + return "asDoubleStream"; + } + } + return null; + } + + /** + * Returns name of the Stream API mapping operation which maps from inType to outType (assuming both types are supported by Stream API) + * + * @param inType input stream element type + * @param outType output stream element type + * @return a name of the mapping operation like "map" or "mapToLong". + */ + @NotNull + public static String getMapOperationName(PsiType inType, @Nullable PsiType outType) { + if(outType instanceof PsiPrimitiveType) { + if(!outType.equals(inType)) { + if(PsiType.INT.equals(outType)) { + return "mapToInt"; + } else if(PsiType.LONG.equals(outType)) { + return "mapToLong"; + } else if(PsiType.DOUBLE.equals(outType)) { + return "mapToDouble"; + } + } + } else if(inType instanceof PsiPrimitiveType) { + return "mapToObj"; + } + return "map"; + } + + @Nullable + public static String getFlatMapOperationName(PsiType inType, PsiType outType) { + if (!(inType instanceof PsiPrimitiveType)) { + if (PsiType.INT.equals(outType)) { + return "flatMapToInt"; + } + else if (PsiType.LONG.equals(outType)) { + return "flatMapToLong"; + } + else if (PsiType.DOUBLE.equals(outType)) { + return "flatMapToDouble"; + } + } else if (!inType.equals(outType)) return null; + return "flatMap"; + } } diff --git a/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java b/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java index 96fdc1ac0f30..5fa5f96814fa 100644 --- a/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.NullableNotNullManager; +import com.intellij.codeInsight.intention.impl.StreamRefactoringUtil; import com.intellij.codeInspection.dataFlow.DfaUtil; import com.intellij.codeInspection.dataFlow.Nullness; import com.intellij.openapi.diagnostic.Logger; @@ -1041,7 +1042,7 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns PsiLambdaExpression newLambda = (PsiLambdaExpression)factory .createExpressionFromText("(" + elementType.getCanonicalText() + " " + name + ")->" + ct.text(body), mapToObjCall); PsiParameter newParameter = ArrayUtil.getFirstElement(newLambda.getParameterList().getParameters()); - replacement += StreamApiUtil.generateMapOperation(newParameter, outElementType, newLambda.getBody()); + replacement += StreamRefactoringUtil.generateMapOperation(newParameter, outElementType, newLambda.getBody()); PsiElement result = ct.replaceAndRestoreComments(mapToObjCall, replacement); LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result); result = JavaCodeStyleManager.getInstance(project).shortenClassReferences(result); diff --git a/java/java-impl/src/com/intellij/codeInspection/streamMigration/CollectMigration.java b/java/java-impl/src/com/intellij/codeInspection/streamMigration/CollectMigration.java index a6835fd64b7d..a751c69e9de2 100644 --- a/java/java-impl/src/com/intellij/codeInspection/streamMigration/CollectMigration.java +++ b/java/java-impl/src/com/intellij/codeInspection/streamMigration/CollectMigration.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection.streamMigration; +import com.intellij.codeInsight.intention.impl.StreamRefactoringUtil; import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.CountingLoopSource; import com.intellij.codeInspection.util.LambdaGenerationUtil; import com.intellij.openapi.diagnostic.Logger; @@ -280,7 +281,7 @@ class CollectMigration extends BaseStreamApiMigration { PsiType addedType = getAddedElementType(myAddCall); PsiExpression mapping = getMapping(); if (addedType == null) addedType = mapping.getType(); - return StreamApiUtil.generateMapOperation(myElement, addedType, mapping); + return StreamRefactoringUtil.generateMapOperation(myElement, addedType, mapping); } public String generateCollector() { @@ -562,7 +563,7 @@ class CollectMigration extends BaseStreamApiMigration { public String generateIntermediate() { PsiExpression mapping = myAppendCall.getArgumentList().getExpressions()[0]; mapping = JavaPsiFacade.getElementFactory(mapping.getProject()).createExpressionFromText(expressionToCharSequence(mapping), mapping); - return StreamApiUtil.generateMapOperation(myElement, null, mapping); + return StreamRefactoringUtil.generateMapOperation(myElement, null, mapping); } @NotNull diff --git a/java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java b/java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java index c953acc8b324..50533520bdc0 100644 --- a/java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.ExceptionUtil; import com.intellij.codeInsight.PsiEquivalenceUtil; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; +import com.intellij.codeInsight.intention.impl.StreamRefactoringUtil; import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool; import com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection; import com.intellij.codeInspection.ProblemHighlightType; @@ -772,7 +773,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo @Override public String createReplacement() { - return StreamApiUtil.generateMapOperation(myVariable, myType, myExpression); + return StreamRefactoringUtil.generateMapOperation(myVariable, myType, myExpression); } @Override diff --git a/java/java-impl/src/com/intellij/codeInspection/util/OptionalUtil.java b/java/java-impl/src/com/intellij/codeInspection/util/OptionalUtil.java index fa2f160f49da..a3ea8061436f 100644 --- a/java/java-impl/src/com/intellij/codeInspection/util/OptionalUtil.java +++ b/java/java-impl/src/com/intellij/codeInspection/util/OptionalUtil.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection.util; import com.intellij.codeInsight.PsiEquivalenceUtil; +import com.intellij.codeInsight.intention.impl.StreamRefactoringUtil; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; @@ -182,13 +183,13 @@ public class OptionalUtil { return qualifier + ".stream()"; } if(arg.getType() != null && elementType.isAssignableFrom(arg.getType())) { - return qualifier + ".stream()" + StreamApiUtil.generateMapOperation(var, elementType, arg); + return qualifier + ".stream()" + StreamRefactoringUtil.generateMapOperation(var, elementType, arg); } } } } } - String flatMapOperationName = StreamApiUtil.getFlatMapOperationName(var.getType(), elementType); + String flatMapOperationName = StreamRefactoringUtil.getFlatMapOperationName(var.getType(), elementType); if(flatMapOperationName != null) { return qualifier + ".stream()."+flatMapOperationName+"(" + LambdaUtil.createLambda(var, trueExpression) + ")"; } diff --git a/java/java-impl/src/com/intellij/refactoring/chainCall/CollectionChainCallExtractor.java b/java/java-impl/src/com/intellij/refactoring/chainCall/CollectionChainCallExtractor.java index 90c6a9915ab0..f0df967d7797 100644 --- a/java/java-impl/src/com/intellij/refactoring/chainCall/CollectionChainCallExtractor.java +++ b/java/java-impl/src/com/intellij/refactoring/chainCall/CollectionChainCallExtractor.java @@ -15,6 +15,7 @@ */ package com.intellij.refactoring.chainCall; +import com.intellij.codeInsight.intention.impl.StreamRefactoringUtil; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; import com.siyeh.ig.psiutils.StreamApiUtil; @@ -39,11 +40,11 @@ public class CollectionChainCallExtractor implements ChainCallExtractor { @Override public String getMethodName(PsiVariable variable, PsiExpression expression, PsiType expressionType) { - return "stream()." + StreamApiUtil.getMapOperationName(variable.getType(), expressionType); + return "stream()." + StreamRefactoringUtil.getMapOperationName(variable.getType(), expressionType); } @Override public String buildChainCall(PsiVariable variable, PsiExpression expression, PsiType expressionType) { - return ".stream()" + StreamApiUtil.generateMapOperation(variable, expressionType, expression); + return ".stream()" + StreamRefactoringUtil.generateMapOperation(variable, expressionType, expression); } } diff --git a/java/java-impl/src/com/intellij/refactoring/chainCall/StreamChainCallExtractor.java b/java/java-impl/src/com/intellij/refactoring/chainCall/StreamChainCallExtractor.java index a86872b70377..02c05991ea66 100644 --- a/java/java-impl/src/com/intellij/refactoring/chainCall/StreamChainCallExtractor.java +++ b/java/java-impl/src/com/intellij/refactoring/chainCall/StreamChainCallExtractor.java @@ -16,6 +16,7 @@ package com.intellij.refactoring.chainCall; import com.intellij.codeInsight.intention.impl.InlineStreamMapAction; +import com.intellij.codeInsight.intention.impl.StreamRefactoringUtil; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; import com.siyeh.ig.psiutils.StreamApiUtil; @@ -53,23 +54,23 @@ public class StreamChainCallExtractor implements ChainCallExtractor { PsiType outType = StreamApiUtil.getStreamElementType(call.getType(), false); String methodName = Objects.requireNonNull(call.getMethodExpression().getReferenceName()); if (methodName.startsWith("flatMap")) { - return Objects.requireNonNull(StreamApiUtil.getFlatMapOperationName(inType, outType)); + return Objects.requireNonNull(StreamRefactoringUtil.getFlatMapOperationName(inType, outType)); } if (methodName.startsWith("map")) { - return StreamApiUtil.getMapOperationName(inType, outType); + return StreamRefactoringUtil.getMapOperationName(inType, outType); } return methodName; } @Override public String getMethodName(PsiVariable variable, PsiExpression expression, PsiType expressionType) { - String shortcutMappingMethod = StreamApiUtil.getShortcutMappingMethod(variable, expressionType, expression); + String shortcutMappingMethod = StreamRefactoringUtil.getShortcutMappingMethod(variable, expressionType, expression); if(shortcutMappingMethod != null) return shortcutMappingMethod; - return StreamApiUtil.getMapOperationName(variable.getType(), expressionType); + return StreamRefactoringUtil.getMapOperationName(variable.getType(), expressionType); } @Override public String buildChainCall(PsiVariable variable, PsiExpression expression, PsiType expressionType) { - return StreamApiUtil.generateMapOperation(variable, expressionType, expression); + return StreamRefactoringUtil.generateMapOperation(variable, expressionType, expression); } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/StreamApiUtil.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/StreamApiUtil.java new file mode 100644 index 000000000000..ca11685d59ca --- /dev/null +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/StreamApiUtil.java @@ -0,0 +1,83 @@ +/* + * Copyright 2000-2017 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. + */ +package com.siyeh.ig.psiutils; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import org.jetbrains.annotations.Contract; + +/** + * @author Tagir Valeev + */ +public class StreamApiUtil { + @Contract("null -> null") + public static PsiType getStreamElementType(PsiType type) { + return getStreamElementType(type, true); + } + + @Contract("null, _ -> null") + public static PsiType getStreamElementType(PsiType type, boolean variableType) { + if(!(type instanceof PsiClassType)) return null; + PsiClass aClass = ((PsiClassType)type).resolve(); + if(com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, false, CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM)) { + return PsiType.INT; + } + if(com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, false, CommonClassNames.JAVA_UTIL_STREAM_LONG_STREAM)) { + return PsiType.LONG; + } + if(com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, false, CommonClassNames.JAVA_UTIL_STREAM_DOUBLE_STREAM)) { + return PsiType.DOUBLE; + } + if(!com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, false, CommonClassNames.JAVA_UTIL_STREAM_STREAM)) { + return null; + } + PsiType streamType = PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_STREAM_STREAM, 0, false); + if (variableType) { + if (streamType instanceof PsiIntersectionType) { + return null; + } + streamType = GenericsUtil.getVariableTypeByExpressionType(streamType); + } + return streamType; + } + + public static boolean isNullOrEmptyStream(PsiExpression expression) { + if(ExpressionUtils.isNullLiteral(expression)) { + return true; + } + if (!(expression instanceof PsiMethodCallExpression)) return false; + PsiMethodCallExpression call = (PsiMethodCallExpression)expression; + String name = call.getMethodExpression().getReferenceName(); + if ((!"empty".equals(name) && !"of".equals(name)) || !(call.getArgumentList().getExpressions().length == 0)) { + return false; + } + PsiMethod method = call.resolveMethod(); + if (method == null || !method.hasModifierProperty(PsiModifier.STATIC)) return false; + PsiClass aClass = method.getContainingClass(); + if(aClass == null) return false; + String qualifiedName = aClass.getQualifiedName(); + return qualifiedName != null && qualifiedName.startsWith("java.util.stream."); + } + + @Contract("null -> false") + public static boolean isSupportedStreamElement(PsiType type) { + if(type == null) return false; + if(type instanceof PsiPrimitiveType) { + return type.equals(PsiType.INT) || type.equals(PsiType.LONG) || type.equals(PsiType.DOUBLE); + } + return true; + } +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/StreamApiUtil.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/StreamApiUtil.java deleted file mode 100644 index c80b089d7c52..000000000000 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/StreamApiUtil.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2000-2017 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. - */ -package com.siyeh.ig.psiutils; - -import com.intellij.codeInspection.util.OptionalUtil; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtil; -import com.intellij.refactoring.util.RefactoringUtil; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Objects; - -/** - * @author Tagir Valeev - */ -public class StreamApiUtil { - @Contract("null -> null") - public static PsiType getStreamElementType(PsiType type) { - return getStreamElementType(type, true); - } - - @Contract("null, _ -> null") - public static PsiType getStreamElementType(PsiType type, boolean variableType) { - if(!(type instanceof PsiClassType)) return null; - PsiClass aClass = ((PsiClassType)type).resolve(); - if(com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, false, CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM)) { - return PsiType.INT; - } - if(com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, false, CommonClassNames.JAVA_UTIL_STREAM_LONG_STREAM)) { - return PsiType.LONG; - } - if(com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, false, CommonClassNames.JAVA_UTIL_STREAM_DOUBLE_STREAM)) { - return PsiType.DOUBLE; - } - if(!com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, false, CommonClassNames.JAVA_UTIL_STREAM_STREAM)) { - return null; - } - PsiType streamType = PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_STREAM_STREAM, 0, false); - if (variableType) { - if (streamType instanceof PsiIntersectionType) { - return null; - } - streamType = GenericsUtil.getVariableTypeByExpressionType(streamType); - } - return streamType; - } - - public static boolean isNullOrEmptyStream(PsiExpression expression) { - if(ExpressionUtils.isNullLiteral(expression)) { - return true; - } - if (!(expression instanceof PsiMethodCallExpression)) return false; - PsiMethodCallExpression call = (PsiMethodCallExpression)expression; - String name = call.getMethodExpression().getReferenceName(); - if ((!"empty".equals(name) && !"of".equals(name)) || !(call.getArgumentList().getExpressions().length == 0)) { - return false; - } - PsiMethod method = call.resolveMethod(); - if (method == null || !method.hasModifierProperty(PsiModifier.STATIC)) return false; - PsiClass aClass = method.getContainingClass(); - if(aClass == null) return false; - String qualifiedName = aClass.getQualifiedName(); - return qualifiedName != null && qualifiedName.startsWith("java.util.stream."); - } - - @Contract("null -> false") - public static boolean isSupportedStreamElement(PsiType type) { - if(type == null) return false; - if(type instanceof PsiPrimitiveType) { - return type.equals(PsiType.INT) || type.equals(PsiType.LONG) || type.equals(PsiType.DOUBLE); - } - return true; - } - - @NotNull - public static String generateMapOperation(PsiVariable variable, @Nullable PsiType outType, PsiElement mapper) { - String shortcutMappingMethod = getShortcutMappingMethod(variable, outType, mapper); - if (shortcutMappingMethod != null) return shortcutMappingMethod.isEmpty() ? "" : "." + shortcutMappingMethod + "()"; - PsiType inType = variable.getType(); - String operationName = getMapOperationName(inType, outType); - if(outType != null && mapper instanceof PsiArrayInitializerExpression) { - mapper = RefactoringUtil.convertInitializerToNormalExpression((PsiExpression)mapper, outType); - } - String typeArgument = mapper instanceof PsiExpression ? OptionalUtil.getMapTypeArgument((PsiExpression)mapper, outType) : ""; - return "." + typeArgument + operationName + - "(" + variable.getName() + "->" + mapper.getText() + ")"; - } - - /** - * Returns the shortcut mapping method name - * - * @param variable mapper input variable - * @param outType output type of the mapper - * @param mapper mapper code - * @return shortcut mapping name ("boxed", "asLongStream", "asDoubleStream") if applicable, empty string if it's - * ditto mapping (no mapping is necessary at all) and null if no shortcut is applicable for given mapper - */ - @Nullable - public static String getShortcutMappingMethod(PsiVariable variable, @Nullable PsiType outType, PsiElement mapper) { - if (!(mapper instanceof PsiExpression)) return null; - PsiExpression expression = PsiUtil.skipParenthesizedExprDown(((PsiExpression)mapper)); - PsiType inType = variable.getType(); - if (expression instanceof PsiTypeCastExpression && inType instanceof PsiPrimitiveType && Objects.equals(expression.getType(), outType)) { - expression = ((PsiTypeCastExpression)expression).getOperand(); - } - if (ExpressionUtils.isReferenceTo(expression, variable)) { - if (!(outType instanceof PsiPrimitiveType)) { - return inType instanceof PsiPrimitiveType ? "boxed" : ""; - } - if (outType.equals(inType)) { - return ""; - } - if (PsiType.LONG.equals(outType) && PsiType.INT.equals(inType)) { - return "asLongStream"; - } - if (PsiType.DOUBLE.equals(outType) && (PsiType.LONG.equals(inType) || PsiType.INT.equals(inType))) { - return "asDoubleStream"; - } - } - return null; - } - - @NotNull - public static String getMapOperationName(PsiType inType, @Nullable PsiType outType) { - if(outType instanceof PsiPrimitiveType) { - if(!outType.equals(inType)) { - if(PsiType.INT.equals(outType)) { - return "mapToInt"; - } else if(PsiType.LONG.equals(outType)) { - return "mapToLong"; - } else if(PsiType.DOUBLE.equals(outType)) { - return "mapToDouble"; - } - } - } else if(inType instanceof PsiPrimitiveType) { - return "mapToObj"; - } - return "map"; - } - - @Nullable - public static String getFlatMapOperationName(PsiType inType, PsiType outType) { - if (!(inType instanceof PsiPrimitiveType)) { - if (PsiType.INT.equals(outType)) { - return "flatMapToInt"; - } - else if (PsiType.LONG.equals(outType)) { - return "flatMapToLong"; - } - else if (PsiType.DOUBLE.equals(outType)) { - return "flatMapToDouble"; - } - } else if (!inType.equals(outType)) return null; - return "flatMap"; - } -}