mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
AddAnnotationPsiFix: support annotating lambda parameter without a type
GitOrigin-RevId: 11fe3fdfa77f1d52c1e122dd790b3375488496f6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
494af61fae
commit
ca4cd28b82
+43
-17
@@ -15,8 +15,11 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.light.LightElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -66,13 +69,11 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
return CodeInsightBundle.message("inspection.i18n.quickfix.annotate.as", shortName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiModifierListOwner getContainer(final PsiFile file, int offset) {
|
||||
public static @Nullable PsiModifierListOwner getContainer(PsiFile file, int offset) {
|
||||
return getContainer(file, offset, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiModifierListOwner getContainer(final PsiFile file, int offset, boolean availableOnReference) {
|
||||
public static @Nullable PsiModifierListOwner getContainer(PsiFile file, int offset, boolean availableOnReference) {
|
||||
PsiReference reference = availableOnReference ? file.findReferenceAt(offset) : null;
|
||||
if (reference != null) {
|
||||
PsiElement target = reference.resolve();
|
||||
@@ -97,14 +98,12 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getText() {
|
||||
public @NotNull String getText() {
|
||||
return myText;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
public @NotNull String getFamilyName() {
|
||||
return CodeInsightBundle.message("intention.add.annotation.family");
|
||||
}
|
||||
|
||||
@@ -174,8 +173,7 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ExternalAnnotationsManager.AnnotationPlace choosePlace(@NotNull PsiModifierListOwner modifierListOwner) {
|
||||
private @NotNull ExternalAnnotationsManager.AnnotationPlace choosePlace(@NotNull PsiModifierListOwner modifierListOwner) {
|
||||
Project project = modifierListOwner.getProject();
|
||||
final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(project);
|
||||
PsiClass aClass = JavaPsiFacade.getInstance(project).findClass(myAnnotation, modifierListOwner.getResolveScope());
|
||||
@@ -213,6 +211,7 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
}
|
||||
|
||||
public static PsiAnnotation addPhysicalAnnotation(String fqn, PsiNameValuePair[] pairs, PsiAnnotationOwner owner) {
|
||||
owner = expandParameterIfNecessary(owner);
|
||||
PsiAnnotation inserted = owner.addAnnotation(fqn);
|
||||
for (PsiNameValuePair pair : pairs) {
|
||||
inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue());
|
||||
@@ -220,6 +219,36 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
return inserted;
|
||||
}
|
||||
|
||||
private static PsiAnnotationOwner expandParameterIfNecessary(PsiAnnotationOwner owner) {
|
||||
if (owner instanceof PsiModifierList) {
|
||||
PsiParameter parameter = ObjectUtils.tryCast(((PsiModifierList)owner).getParent(), PsiParameter.class);
|
||||
if (parameter != null && parameter.getTypeElement() == null) {
|
||||
PsiParameterList list = ObjectUtils.tryCast(parameter.getParent(), PsiParameterList.class);
|
||||
if (list != null && list.getParent() instanceof PsiLambdaExpression) {
|
||||
PsiParameter[] parameters = list.getParameters();
|
||||
int index = ArrayUtil.indexOf(parameters, parameter);
|
||||
PsiParameterList newList;
|
||||
if (PsiUtil.isLanguageLevel11OrHigher(list)) {
|
||||
String newListText = StreamEx.of(parameters).map(p -> "var " + p.getName()).joining(",", "(", ")");
|
||||
newList = ((PsiLambdaExpression)JavaPsiFacade.getElementFactory(list.getProject())
|
||||
.createExpressionFromText(newListText+" -> {}", null)).getParameterList();
|
||||
newList = (PsiParameterList)new CommentTracker().replaceAndRestoreComments(list, newList);
|
||||
} else {
|
||||
newList = LambdaUtil.specifyLambdaParameterTypes((PsiLambdaExpression)list.getParent());
|
||||
}
|
||||
if (newList != null) {
|
||||
list = newList;
|
||||
parameter = list.getParameter(index);
|
||||
LOG.assertTrue(parameter != null);
|
||||
owner = parameter.getModifierList();
|
||||
LOG.assertTrue(owner != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return owner;
|
||||
}
|
||||
|
||||
public static void removePhysicalAnnotations(@NotNull PsiModifierListOwner owner, String @NotNull ... fqns) {
|
||||
for (String fqn : fqns) {
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(owner, true, fqn);
|
||||
@@ -247,8 +276,7 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
* @param owner an element to add the annotation
|
||||
* @return newly created fix or null if adding nullability annotation is impossible for the specified element.
|
||||
*/
|
||||
@Nullable
|
||||
public static AddAnnotationPsiFix createAddNullableFix(PsiModifierListOwner owner) {
|
||||
public static @Nullable AddAnnotationPsiFix createAddNullableFix(PsiModifierListOwner owner) {
|
||||
NullableNotNullManager manager = NullableNotNullManager.getInstance(owner.getProject());
|
||||
return createAddNullableNotNullFix(owner, manager.getDefaultNullable(), manager.getNotNulls());
|
||||
}
|
||||
@@ -259,15 +287,13 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
* @param owner an element to add the annotation
|
||||
* @return newly created fix or null if adding nullability annotation is impossible for the specified element.
|
||||
*/
|
||||
@Nullable
|
||||
public static AddAnnotationPsiFix createAddNotNullFix(PsiModifierListOwner owner) {
|
||||
public static @Nullable AddAnnotationPsiFix createAddNotNullFix(PsiModifierListOwner owner) {
|
||||
NullableNotNullManager manager = NullableNotNullManager.getInstance(owner.getProject());
|
||||
return createAddNullableNotNullFix(owner, manager.getDefaultNotNull(), manager.getNullables());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static AddAnnotationPsiFix createAddNullableNotNullFix(PsiModifierListOwner owner, String annotationToAdd,
|
||||
List<String> annotationsToRemove) {
|
||||
private static @Nullable AddAnnotationPsiFix createAddNullableNotNullFix(PsiModifierListOwner owner, String annotationToAdd,
|
||||
List<String> annotationsToRemove) {
|
||||
if (!isNullabilityAnnotationApplicable(owner)) return null;
|
||||
return new AddAnnotationPsiFix(annotationToAdd, owner, PsiNameValuePair.EMPTY_ARRAY, ArrayUtilRt.toStringArray(annotationsToRemove));
|
||||
}
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ public class SimplifyOptionalCallChainsInspection extends AbstractBaseJavaLocalI
|
||||
PsiMethodReferenceExpression methodRef = (PsiMethodReferenceExpression)expression;
|
||||
PsiLambdaExpression lambda = LambdaRefactoringUtil.createLambda(methodRef, true);
|
||||
if (lambda != null) {
|
||||
LambdaRefactoringUtil.specifyLambdaParameterTypes(methodRef.getFunctionalInterfaceType(), lambda);
|
||||
LambdaUtil.specifyLambdaParameterTypes(methodRef.getFunctionalInterfaceType(), lambda);
|
||||
return lambda;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ public abstract class FunctionHelper {
|
||||
public String tryLightTransform() {
|
||||
PsiLambdaExpression lambdaExpression = LambdaRefactoringUtil.createLambda(myMethodRef, true);
|
||||
if(lambdaExpression == null) return null;
|
||||
String typedParamList = LambdaRefactoringUtil.createLambdaParameterListWithFormalTypes(myType, lambdaExpression, false);
|
||||
String typedParamList = LambdaUtil.createLambdaParameterListWithFormalTypes(myType, lambdaExpression, false);
|
||||
if(typedParamList != null && lambdaExpression.getBody() != null) {
|
||||
lambdaExpression = (PsiLambdaExpression)JavaPsiFacade.getElementFactory(myMethodRef.getProject())
|
||||
.createExpressionFromText(typedParamList + "->" + lambdaExpression.getBody().getText(), myMethodRef);
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.introduceField.ElementToWorkOn;
|
||||
@@ -72,7 +71,7 @@ public class LambdaRefactoringUtil {
|
||||
final PsiType functionalInterfaceType = referenceExpression.getFunctionalInterfaceType();
|
||||
boolean needToSpecifyFormalTypes = !doNotAddParameterTypes && !isInferredSameTypeAfterConversion(lambdaExpression, referenceExpression);
|
||||
if (needToSpecifyFormalTypes) {
|
||||
PsiParameterList typedParamList = specifyLambdaParameterTypes(functionalInterfaceType, lambdaExpression);
|
||||
PsiParameterList typedParamList = LambdaUtil.specifyLambdaParameterTypes(functionalInterfaceType, lambdaExpression);
|
||||
if (typedParamList == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -285,52 +284,6 @@ public class LambdaRefactoringUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static @Nullable String createLambdaParameterListWithFormalTypes(PsiType functionalInterfaceType,
|
||||
PsiLambdaExpression lambdaExpression,
|
||||
boolean checkApplicability) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("(");
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType);
|
||||
LOG.assertTrue(interfaceMethod != null);
|
||||
final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
|
||||
final PsiParameter[] lambdaParameters = lambdaExpression.getParameterList().getParameters();
|
||||
if (parameters.length != lambdaParameters.length) return null;
|
||||
final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiType psiType = substitutor.substitute(parameters[i].getType());
|
||||
if (psiType == null) return null;
|
||||
if (!PsiTypesUtil.isDenotableType(psiType, lambdaExpression)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
buf.append(checkApplicability ? psiType.getPresentableText() : psiType.getCanonicalText())
|
||||
.append(" ")
|
||||
.append(lambdaParameters[i].getName());
|
||||
if (i < parameters.length - 1) {
|
||||
buf.append(", ");
|
||||
}
|
||||
}
|
||||
buf.append(")");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static @Nullable PsiParameterList specifyLambdaParameterTypes(PsiLambdaExpression lambdaExpression) {
|
||||
return specifyLambdaParameterTypes(lambdaExpression.getFunctionalInterfaceType(), lambdaExpression);
|
||||
}
|
||||
|
||||
public static @Nullable PsiParameterList specifyLambdaParameterTypes(PsiType functionalInterfaceType,
|
||||
@NotNull PsiLambdaExpression lambdaExpression) {
|
||||
String typedParamList = createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression, false);
|
||||
if (typedParamList != null) {
|
||||
PsiParameterList paramListWithFormalTypes = JavaPsiFacade.getElementFactory(lambdaExpression.getProject())
|
||||
.createMethodFromText("void foo" + typedParamList, lambdaExpression).getParameterList();
|
||||
return (PsiParameterList)JavaCodeStyleManager.getInstance(lambdaExpression.getProject())
|
||||
.shortenClassReferences(lambdaExpression.getParameterList().replace(paramListWithFormalTypes));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void simplifyToExpressionLambda(@NotNull PsiLambdaExpression lambdaExpression) {
|
||||
final PsiElement body = lambdaExpression.getBody();
|
||||
final PsiExpression singleExpression = RedundantLambdaCodeBlockInspection.isCodeBlockRedundant(body);
|
||||
|
||||
@@ -1100,4 +1100,50 @@ public class LambdaUtil {
|
||||
}
|
||||
return actualClass;
|
||||
}
|
||||
|
||||
public static @Nullable String createLambdaParameterListWithFormalTypes(PsiType functionalInterfaceType,
|
||||
PsiLambdaExpression lambdaExpression,
|
||||
boolean checkApplicability) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("(");
|
||||
final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(functionalInterfaceType);
|
||||
if (interfaceMethod == null) return null;
|
||||
final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
|
||||
final PsiParameter[] lambdaParameters = lambdaExpression.getParameterList().getParameters();
|
||||
if (parameters.length != lambdaParameters.length) return null;
|
||||
final PsiSubstitutor substitutor = getSubstitutor(interfaceMethod, resolveResult);
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiType psiType = substitutor.substitute(parameters[i].getType());
|
||||
if (psiType == null) return null;
|
||||
if (!PsiTypesUtil.isDenotableType(psiType, lambdaExpression)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
buf.append(checkApplicability ? psiType.getPresentableText() : psiType.getCanonicalText())
|
||||
.append(" ")
|
||||
.append(lambdaParameters[i].getName());
|
||||
if (i < parameters.length - 1) {
|
||||
buf.append(", ");
|
||||
}
|
||||
}
|
||||
buf.append(")");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static @Nullable PsiParameterList specifyLambdaParameterTypes(PsiLambdaExpression lambdaExpression) {
|
||||
return specifyLambdaParameterTypes(lambdaExpression.getFunctionalInterfaceType(), lambdaExpression);
|
||||
}
|
||||
|
||||
public static @Nullable PsiParameterList specifyLambdaParameterTypes(PsiType functionalInterfaceType,
|
||||
@NotNull PsiLambdaExpression lambdaExpression) {
|
||||
String typedParamList = createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression, false);
|
||||
if (typedParamList != null) {
|
||||
PsiParameterList paramListWithFormalTypes = JavaPsiFacade.getElementFactory(lambdaExpression.getProject())
|
||||
.createMethodFromText("void foo" + typedParamList, lambdaExpression).getParameterList();
|
||||
return (PsiParameterList)JavaCodeStyleManager.getInstance(lambdaExpression.getProject())
|
||||
.shortenClassReferences(lambdaExpression.getParameterList().replace(paramListWithFormalTypes));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
// "Annotate parameter 'sb' as @NonNls" "true"
|
||||
class Foo {
|
||||
java.util.function.Consumer<StringBuilder> consumerTest() {
|
||||
return (@NonNls var sb) -> sb.append("foo");
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
// "Annotate parameter 'sb' as @NonNls" "true"
|
||||
class Foo {
|
||||
java.util.function.Consumer<StringBuilder> consumerTest() {
|
||||
return (@NonNls StringBuilder sb) -> sb.append("foo");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Annotate parameter 'sb' as @NonNls" "true"
|
||||
class Foo {
|
||||
java.util.function.Consumer<StringBuilder> consumerTest() {
|
||||
return sb -> sb.append("<caret>foo");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Annotate parameter 'sb' as @NonNls" "true"
|
||||
class Foo {
|
||||
java.util.function.Consumer<StringBuilder> consumerTest() {
|
||||
return sb -> sb.append("<caret>foo");
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -19,11 +19,12 @@ import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCa
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.i18n.I18nInspection;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.impl.PsiDocumentManagerBase;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -66,7 +67,7 @@ public class I18nQuickFixTest extends LightQuickFixParameterizedTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LanguageLevel getLanguageLevel() {
|
||||
return LanguageLevel.JDK_1_5;
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk18();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -20,7 +20,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
@@ -62,8 +61,8 @@ public class LambdaParameterTypeCanBeSpecifiedInspection extends BaseInspection
|
||||
final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
|
||||
if (functionalInterfaceType != null &&
|
||||
LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType) != null) {
|
||||
final String inferredTypesText = LambdaRefactoringUtil.createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression,
|
||||
true);
|
||||
final String inferredTypesText = LambdaUtil.createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression,
|
||||
true);
|
||||
if (inferredTypesText != null) {
|
||||
PsiElement nextElement = PsiTreeUtil.skipWhitespacesAndCommentsForward(parameterList);
|
||||
if (PsiUtil.isJavaToken(nextElement, JavaTokenType.ARROW)) {
|
||||
@@ -100,7 +99,7 @@ public class LambdaParameterTypeCanBeSpecifiedInspection extends BaseInspection
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (element instanceof PsiLambdaExpression) {
|
||||
LambdaRefactoringUtil.specifyLambdaParameterTypes((PsiLambdaExpression)element);
|
||||
LambdaUtil.specifyLambdaParameterTypes((PsiLambdaExpression)element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -21,7 +21,6 @@ import com.intellij.refactoring.extractMethod.ExtractMethodProcessor;
|
||||
import com.intellij.refactoring.extractMethod.PrepareFailedException;
|
||||
import com.intellij.refactoring.rename.RenamePsiElementProcessor;
|
||||
import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.refactoring.util.duplicates.Match;
|
||||
import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler;
|
||||
@@ -64,7 +63,7 @@ public class ExtractToMethodReferenceIntention extends BaseElementAtCaretIntenti
|
||||
}
|
||||
|
||||
//can types be specified
|
||||
if (LambdaRefactoringUtil.createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression, false) == null) {
|
||||
if (LambdaUtil.createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression, false) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -102,7 +101,7 @@ public class ExtractToMethodReferenceIntention extends BaseElementAtCaretIntenti
|
||||
PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
|
||||
|
||||
String parameters =
|
||||
LambdaRefactoringUtil.createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression, false) + "{}";
|
||||
LambdaUtil.createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression, false) + "{}";
|
||||
String targetMethodName = getUniqueMethodName(targetClass, elementFactory, functionalInterfaceType, parameters);
|
||||
|
||||
PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression);
|
||||
|
||||
Reference in New Issue
Block a user