String () { String methodName = shouldShowMethodName() ? myMethod.getName() : ""; String type = myQuick ? "" : getOptionalLambdaType(); String params = StringUtil.join(myMethod.getParameterList().getParameters(), psiParameter -> psiParameter.getName(), ", "); return type + methodName + "(" + params + ") " + myBuilder.rightArrow() + " {"; } @Nullable static ClosureFolding prepare(@NotNull PsiAnonymousClass anonymousClass, boolean quick, @NotNull JavaFoldingBuilderBase builder) { PsiElement parent = anonymousClass.getParent(); if (parent instanceof PsiNewExpression && hasNoArguments((PsiNewExpression)parent)) { PsiClass baseClass = quick ? null : anonymousClass.getBaseClassType().resolve(); if (hasOnlyOneLambdaMethod(anonymousClass, !quick) && (quick || seemsLikeLambda(baseClass, anonymousClass))) { PsiMethod method = anonymousClass.getMethods()[0]; PsiCodeBlock body = method.getBody(); if (body != null) { return new ClosureFolding(anonymousClass, (PsiNewExpression)parent, quick, baseClass, builder, method, body); } } } return null; } private static boolean hasNoArguments(@NotNull PsiNewExpression expression) { PsiExpressionList argumentList = expression.getArgumentList(); return argumentList != null && argumentList.isEmpty(); } private static boolean hasOnlyOneLambdaMethod(@NotNull PsiAnonymousClass anonymousClass, boolean checkResolve) { PsiField[] fields = anonymousClass.getFields(); if (fields.length != 0 && (fields.length != 1 || !CommonClassNames.SERIAL_VERSION_UID_FIELD_NAME.equals(fields[0].getName()) || !fields[0].hasModifierProperty(PsiModifier.STATIC))) { return false; } if (anonymousClass.getInitializers().length != 0 || anonymousClass.getInnerClasses().length != 0 || anonymousClass.getMethods().length != 1) { return false; } PsiMethod method = anonymousClass.getMethods()[0]; if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) { return false; } if (checkResolve) { for (PsiClassType type : method.getThrowsList().getReferencedTypes()) { if (type.resolve() == null) { return false; } } } return true; } static boolean seemsLikeLambda(@Nullable PsiClass baseClass, @NotNull PsiElement context) { if (baseClass == null || !PsiUtil.hasDefaultConstructor(baseClass, true)) return false; return !PsiUtil.isLanguageLevel8OrHigher(context) || !LambdaUtil.isFunctionalClass(baseClass); } @NotNull private String getOptionalLambdaType() { if (myBuilder.shouldShowExplicitLambdaType(myAnonymousClass, myNewExpression)) { String baseClassName = Objects.requireNonNull(myAnonymousClass.getBaseClassType().resolve()).getName(); if (baseClassName != null) { return "(" + baseClassName + ") "; } } return ""; } private boolean shouldShowMethodName() { if (myBaseClass == null || !myBaseClass.hasModifierProperty(PsiModifier.ABSTRACT)) return true; for (PsiMethod method : myBaseClass.getMethods()) { if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { return false; } } try { return OverrideImplementExploreUtil.getMethodSignaturesToImplement(myBaseClass).isEmpty(); } catch (IndexNotReadyException e) { return true; } } }