String (PsiMethodReferenceExpression referenceExpression) { PsiType functionalInterfaceType = referenceExpression.getFunctionalInterfaceType(); final PsiElement resolve = referenceExpression.resolve(); if (resolve == null) { return null; } final PsiClassType.ClassResolveResult functionalInterfaceResolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType); if (interfaceMethod == null) { return null; } final PsiSubstitutor psiSubstitutor = LambdaUtil.getSubstitutor(interfaceMethod, functionalInterfaceResolveResult); final MethodSignature signature = interfaceMethod.getSignature(psiSubstitutor); final boolean isReceiver; if (resolve instanceof PsiMethod method){ isReceiver = PsiMethodReferenceUtil.isResolvedBySecondSearch(referenceExpression, signature, method.isVarArgs(), method.hasModifierProperty(PsiModifier.STATIC), method.getParameterList().getParametersCount()); } else { isReceiver = false; } final PsiParameter[] psiParameters = resolve instanceof PsiMethod method ? method.getParameterList().getParameters() : null; final PsiParameterList parameterList = interfaceMethod.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); final Map<PsiParameter, String> map = new HashMap<>(); final UniqueNameGenerator nameGenerator = new UniqueNameGenerator(); final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(referenceExpression.getProject()); Function<PsiParameter, String> paramPresentationFunction = parameter -> { final int parameterIndex = parameterList.getParameterIndex(parameter); String baseName; if (isReceiver && parameterIndex == 0) { final SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, psiSubstitutor.substitute(parameter.getType())); baseName = nameInfo.names.length > 0 ? nameInfo.names[0] : parameter.getName(); } else { String initialName; if (psiParameters != null) { final int idx = parameterIndex - (isReceiver ? 1 : 0); initialName = psiParameters.length > 0 ? psiParameters[idx < psiParameters.length ? idx : psiParameters.length - 1].getName() : parameter.getName(); } else { initialName = parameter.getName(); } if ("_".equals(initialName)) { SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, psiSubstitutor.substitute(parameter.getType())); if (nameInfo.names.length > 0) { initialName = nameInfo.names[0]; } } baseName = codeStyleManager.variableNameToPropertyName(initialName, VariableKind.PARAMETER); } String parameterName = nameGenerator.generateUniqueName(codeStyleManager.suggestUniqueVariableName(baseName, referenceExpression, true)); map.put(parameter, parameterName); return parameterName; }; @NonNls StringBuilder buf = new StringBuilder(); if (parameters.length == 1) { buf.append(paramPresentationFunction.fun(parameters[0])); } else { buf.append("(").append(StringUtil.join(parameters, paramPresentationFunction, ", ")).append(")"); } buf.append(" -> "); final JavaResolveResult resolveResult = referenceExpression.advancedResolve(false); final PsiElement resolveElement = resolveResult.getElement(); if (resolveElement instanceof PsiMember member) { buf.append("{"); if (!PsiTypes.voidType().equals(interfaceMethod.getReturnType())) { buf.append("return "); } final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(referenceExpression); final PsiElement qualifier = referenceExpression.getQualifier(); PsiClass containingClass = qualifierResolveResult.getContainingClass(); final boolean onArrayRef = PsiUtil.isArrayClass(containingClass); final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement(); if (isReceiver){ buf.append(map.get(parameters[0])).append("."); } else { if (!(referenceNameElement instanceof PsiKeyword)) { if (qualifier instanceof PsiTypeElement typeElement) { final PsiJavaCodeReferenceElement referenceElement = typeElement.getInnermostComponentReferenceElement(); if (referenceElement != null && !PsiTreeUtil.isAncestor(containingClass, referenceExpression, false)) { buf.append(referenceElement.getReferenceName()).append("."); } } else if (qualifier != null && !isQualifierUnnecessary(qualifier, containingClass)) { buf.append(qualifier.getText()).append("."); } } } //new or method name buf.append(referenceExpression.getReferenceName()); if (referenceNameElement instanceof PsiKeyword) { //class name buf.append(" "); if (onArrayRef) { if (qualifier instanceof PsiTypeElement typeElement) { final PsiType type = typeElement.getType(); int dim = type.getArrayDimensions(); buf.append(type.getDeepComponentType().getCanonicalText()); buf.append("["); buf.append(map.get(parameters[0])); buf.append("]"); while (--dim > 0) { buf.append("[]"); } } } else { buf.append(getMemberQualifier(member)); final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); LOG.assertTrue(containingClass != null); if (containingClass.hasTypeParameters() && ContainerUtil.all(containingClass.getTypeParameters(), tp -> substitutor.substitute(tp) != null)) { buf.append("<").append(StringUtil.join(containingClass.getTypeParameters(), parameter -> { final PsiType psiType = substitutor.substitute(parameter); LOG.assertTrue(psiType != null); return psiType.getCanonicalText(); }, ", ")).append(">"); } } } if (!onArrayRef || !(referenceNameElement instanceof PsiKeyword) || isReceiver) { //param list buf.append("("); boolean first = true; for (int i = isReceiver ? 1 : 0; i < parameters.length; i++) { PsiParameter parameter = parameters[i]; if (!first) { buf.append(", "); } else { first = false; } buf.append(map.get(parameter)); } buf.append(")"); } buf.append(";}"); } return buf.toString(); }