diff --git a/src/main/java/de/plushnikov/intellij/plugin/processor/clazz/builder/BuilderPreDefinedInnerClassMethodProcessor.java b/src/main/java/de/plushnikov/intellij/plugin/processor/clazz/builder/BuilderPreDefinedInnerClassMethodProcessor.java index ce1ea1ee9..7a0504dc3 100644 --- a/src/main/java/de/plushnikov/intellij/plugin/processor/clazz/builder/BuilderPreDefinedInnerClassMethodProcessor.java +++ b/src/main/java/de/plushnikov/intellij/plugin/processor/clazz/builder/BuilderPreDefinedInnerClassMethodProcessor.java @@ -1,6 +1,12 @@ package de.plushnikov.intellij.plugin.processor.clazz.builder; import com.intellij.psi.*; +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiVariable; import de.plushnikov.intellij.plugin.processor.field.AccessorsInfo; import de.plushnikov.intellij.plugin.processor.handler.BuilderHandler; import lombok.Builder; @@ -24,7 +30,16 @@ public BuilderPreDefinedInnerClassMethodProcessor(@NotNull BuilderHandler builde } protected void generatePsiElements(@NotNull PsiClass psiParentClass, @Nullable PsiMethod psiParentMethod, @NotNull PsiClass psiBuilderClass, @NotNull PsiAnnotation psiAnnotation, @NotNull List target) { - final PsiType psiBuilderType = builderHandler.getBuilderType(psiParentClass, psiParentMethod); + final Collection builderFieldsOrParameters; + if (null == psiParentMethod) { + builderFieldsOrParameters = builderHandler.getBuilderFields(psiParentClass, Collections.emptySet(), AccessorsInfo.EMPTY); + } else { + builderFieldsOrParameters = builderHandler.getBuilderParameters(psiParentMethod, Collections.emptySet()); + } + + target.addAll(builderHandler.createConstructors(psiBuilderClass, psiAnnotation)); + target.addAll(builderHandler.createMethods(psiParentClass, psiParentMethod, psiBuilderClass, psiAnnotation, builderFieldsOrParameters)); + if (null == psiParentMethod) { final Collection builderFields = builderHandler.getBuilderFields(psiParentClass, Collections.emptySet(), AccessorsInfo.EMPTY); target.addAll(builderHandler.createConstructors(psiBuilderClass, psiAnnotation)); diff --git a/src/main/java/de/plushnikov/intellij/plugin/processor/handler/BuilderHandler.java b/src/main/java/de/plushnikov/intellij/plugin/processor/handler/BuilderHandler.java index d8e2a6490..acc1336b8 100644 --- a/src/main/java/de/plushnikov/intellij/plugin/processor/handler/BuilderHandler.java +++ b/src/main/java/de/plushnikov/intellij/plugin/processor/handler/BuilderHandler.java @@ -179,18 +179,14 @@ public boolean notExistInnerClass(@NotNull PsiClass psiClass, @Nullable PsiMetho return null == innerBuilderClass; } - private PsiType getBuilderType(@NotNull PsiClass psiClass) { - return getBuilderType(psiClass, null); - } - - public PsiType getBuilderType(@NotNull PsiClass psiClass, @Nullable PsiMethod psiMethod) { - final PsiType psiBuilderTargetClass; + private PsiType getReturnTypeOfBuildMethod(@NotNull PsiClass psiClass, @Nullable PsiMethod psiMethod) { + final PsiType result; if (null == psiMethod || psiMethod.isConstructor()) { - psiBuilderTargetClass = PsiClassUtil.getTypeWithGenerics(psiClass); + result = PsiClassUtil.getTypeWithGenerics(psiClass); } else { - psiBuilderTargetClass = psiMethod.getReturnType(); + result = psiMethod.getReturnType(); } - return psiBuilderTargetClass; + return result; } @NotNull @@ -303,9 +299,7 @@ public PsiClass createBuilderClass(@NotNull PsiClass psiClass, @NotNull PsiMetho ччччч final Collection builderParameters = getBuilderParameters(psiMethod, Collections.emptySet()); builderClass.withFields(generateFields(builderParameters, builderClass, AccessorsInfo.EMPTY)); - - final PsiType psiBuilderType = getBuilderType(psiClass, psiMethod); - builderClass.withMethods(createMethods(psiClass, psiMethod, builderClass, psiBuilderType, psiAnnotation, builderParameters)); + builderClass.withMethods(createMethods(psiClass, psiMethod, builderClass, psiAnnotation, builderParameters)); return builderClass; @@ -313,7 +307,6 @@ public PsiClass createBuilderClass(@NotNull PsiClass psiClass, @NotNull PsiMetho @NotNull public PsiClass createBuilderClass(@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAnnotation) { - final PsiType psiBuilderType = getBuilderType(psiClass); final String builderClassName = getBuilderClassName(psiClass, psiAnnotation); LombokLightClassBuilder builderClass = createBuilderClass(psiClass, psiClass, builderClassName, true, psiAnnotation); @@ -322,25 +315,29 @@ public PsiClass createBuilderClass(@NotNull PsiClass psiClass, @NotNull PsiAnnot final AccessorsInfo accessorsInfo = AccessorsInfo.build(psiClass); final Collection psiFields = getBuilderFields(psiClass, Collections.emptySet(), accessorsInfo); PsiSubstitutor builderSubstitutor = getBuilderSubstitutor(psiClass, builderClass); - builderClass.withFields(generateFields(psiFields, builderClass, accessorsInfo, builderSubstitutor)); - builderClass.withMethods(createMethods(psiClass, null, builderClass, psiBuilderType, psiAnnotation, psiFields, builderSubstitutor)); + builderClass.withFields(generateFields(psiFields, builderClass, accessorsInf, builderSubstitutoro)); + builderClass.withMethods(createMethods(psiClass, null, builderClass, psiAnnotation, psiFields, builderSubstitutor)); return builderClass; } @NotNull - public Collection createMethods(@NotNull PsiClass psiParentClass, @Nullable PsiMethod psiMethod, @NotNull PsiClass psiBuilderClass, @NotNull PsiType psiBuilderType, @NotNull PsiAnnotation psiAnnotation, @NotNull Collection psiVariables, PsiSubstitutor builderSubstitutor) { + public Collection createMethods(@NotNull PsiClass psiParentClass, @Nullable PsiMethod psiMethod, @NotNull PsiClass psiBuilderClass, @NotNull PsiAnnotation psiAnnotation, @NotNull Collection psiVariables, PsiSubstitutor builderSubstitutor) { final Collection methodsIntern = PsiClassUtil.collectClassMethodsIntern(psiBuilderClass); final Set existedMethodNames = new HashSet(methodsIntern.size()); for (PsiMethod existedMethod : methodsIntern) { existedMethodNames.add(existedMethod.getName()); } - List psiMethods = new ArrayList(); + final List psiMethods = new ArrayList(); // use AccessorsInfo only for @Builder on class, not on method final AccessorsInfo accessorsInfo = null == psiMethod ? AccessorsInfo.build(psiParentClass) : AccessorsInfo.EMPTY; + final boolean fluentBuilder = isFluentBuilder(psiAnnotation); + final PsiType psiBuilderClassType = PsiClassUtil.getTypeWithGenerics(psiBuilderClass); + final PsiType returnType = createSetterReturnType(psiAnnotation, psiBuilderClassType); + final StringBuilder buildMethodPrepareString = new StringBuilder(psiVariables.size() * 20); final StringBuilder buildMethodParameterString = new StringBuilder(psiVariables.size() * 20); for (PsiVariable psiVariable : psiVariables) { @@ -351,9 +348,6 @@ public Collection createMethods(@NotNull PsiClass psiParentClass, @Nu // skip methods already defined in builder class if (!existedMethodNames.contains(fieldName)) { - final boolean fluentBuilder = isFluentBuilder(psiAnnotation); - final PsiType returnType = createSetterReturnType(psiAnnotation, PsiClassUtil.getTypeWithGenerics(psiBuilderClass)); - final String singularName = handler.createSingularName(singularAnnotation, fieldName); handler.addBuilderMethod(psiMethods, psiVariable, fieldName, psiBuilderClass, fluentBuilder, returnType, singularName, builderSubstitutor); } @@ -369,9 +363,13 @@ public Collection createMethods(@NotNull PsiClass psiParentClass, @Nu if (buildMethodParameterString.length() > 0) { buildMethodParameterString.deleteCharAt(buildMethodParameterString.length() - 1); } + sss psiMethods.add(createBuildMethod(psiParentClass, psiMethod, psiBuilderClass, builderSubstitutor.substitute(psiBuilderType), buildMethodName, buildMethodPrepareString.toString(), buildMethodParameterString.toString())); + psiMethods.add(createBuildMethod(psiParentClass, psiMethod, psiBuilderClass, + buildMethodName, buildMethodPrepareString.toString(), buildMethodParameterString.toString())); } + if (!existedMethodNames.contains(ToStringProcessor.METHOD_NAME)) { psiMethods.add(toStringProcessor.createToStringMethod(psiBuilderClass, Arrays.asList(psiBuilderClass.getFields()), psiAnnotation)); } @@ -474,15 +472,16 @@ public Collection getBuilderParameters(@NotNull PsiMethod psiMetho } @NotNull - private PsiMethod createBuildMethod(@NotNull PsiClass parentClass, @Nullable PsiMethod psiMethod, @NotNull PsiClass builderClass, @NotNull PsiType psiBuilderType, + private PsiMethod createBuildMethod(@NotNull PsiClass parentClass, @Nullable PsiMethod psiMethod, @NotNull PsiClass builderClass, @NotNull String buildMethodName, @NotNull String buildMethodPrepare, @NotNull String buildMethodParameters) { + final PsiType buildMethodReturnType = getReturnTypeOfBuildMethod(parentClass, psiMethod); final LombokLightMethodBuilder methodBuilder = new LombokLightMethodBuilder(parentClass.getManager(), buildMethodName) - .withMethodReturnType(psiBuilderType) + .withMethodReturnType(buildMethodReturnType) .withContainingClass(builderClass) .withNavigationElement(parentClass) .withModifier(PsiModifier.PUBLIC) - .withBody(createBuildMethodCodeBlock(psiMethod, builderClass, psiBuilderType, buildMethodPrepare, buildMethodParameters)); + .withBody(createBuildMethodCodeBlock(psiMethod, builderClass, buildMethodReturnType, buildMethodPrepare, buildMethodParameters)); if (null == psiMethod) { final Collection classConstructors = PsiClassUtil.collectClassConstructorIntern(parentClass); @@ -498,35 +497,29 @@ private PsiMethod createBuildMethod(@NotNull PsiClass parentClass, @Nullable Psi } @NotNull - private PsiCodeBlock createBuildMethodCodeBlock(@Nullable PsiMethod psiMethod, @NotNull PsiClass builderClass, @NotNull PsiType psiBuilderType, + private PsiCodeBlock createBuildMethodCodeBlock(@Nullable PsiMethod psiMethod, @NotNull PsiClass psiClass, @NotNull PsiType buildMethodReturnType, @NotNull String buildMethodPrepare, @NotNull String buildMethodParameters) { final String blockText; + if (isShouldGenerateFullBodyBlock()) { - final String codeBlockFormat; - final String callExpressionText; - if (null == psiMethod) { + final String codeBlockFormat, callExpressionText; + + if (null == psiMethod || psiMethod.isConstructor()) { codeBlockFormat = "%s\n return new %s(%s);"; - callExpressionText = psiBuilderType.getPresentableText(); + callExpressionText = buildMethodReturnType.getPresentableText(); } else { - if (PsiType.VOID.equals(psiBuilderType)) { + if (PsiType.VOID.equals(buildMethodReturnType)) { codeBlockFormat = "%s\n %s(%s);"; - } else if (psiMethod.isConstructor()) { - codeBlockFormat = "%s\n return new %s(%s);"; } else { codeBlockFormat = "%s\n return %s(%s);"; } - - if (psiMethod.isConstructor()) { - callExpressionText = psiMethod.getName(); - } else { - callExpressionText = calculateCallExpressionForMethod(psiMethod, builderClass); - } + callExpressionText = calculateCallExpressionForMethod(psiMethod, psiClass); } blockText = String.format(codeBlockFormat, buildMethodPrepare, callExpressionText, buildMethodParameters); } else { - blockText = "return " + PsiTypeUtil.getReturnValueOfType(psiBuilderType) + ";"; + blockText = "return " + PsiTypeUtil.getReturnValueOfType(buildMethodReturnType) + ";"; } - return PsiMethodUtil.createCodeBlockFromText(blockText, builderClass); + return PsiMethodUtil.createCodeBlockFromText(blockText, psiClass); } @NotNull