Skip to content

Commit

Permalink
cleanup builder type logic
Browse files Browse the repository at this point in the history
  • Loading branch information
mplushnikov committed Jan 6, 2017
1 parent a8cbaed commit d652868
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 40 deletions.
@@ -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;
Expand All @@ -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<? super PsiElement> target) {
final PsiType psiBuilderType = builderHandler.getBuilderType(psiParentClass, psiParentMethod);
final Collection<? extends PsiVariable> builderFieldsOrParameters;
if (null == psiParentMethod) {
builderFieldsOrParameters = builderHandler.getBuilderFields(psiParentClass, Collections.<PsiField>emptySet(), AccessorsInfo.EMPTY);
} else {
builderFieldsOrParameters = builderHandler.getBuilderParameters(psiParentMethod, Collections.<PsiField>emptySet());
}

target.addAll(builderHandler.createConstructors(psiBuilderClass, psiAnnotation));
target.addAll(builderHandler.createMethods(psiParentClass, psiParentMethod, psiBuilderClass, psiAnnotation, builderFieldsOrParameters));

if (null == psiParentMethod) {
final Collection<PsiField> builderFields = builderHandler.getBuilderFields(psiParentClass, Collections.<PsiField>emptySet(), AccessorsInfo.EMPTY);
target.addAll(builderHandler.createConstructors(psiBuilderClass, psiAnnotation));
Expand Down
Expand Up @@ -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
Expand Down Expand Up @@ -303,17 +299,14 @@ public PsiClass createBuilderClass(@NotNull PsiClass psiClass, @NotNull PsiMetho
ччччч
final Collection<PsiParameter> builderParameters = getBuilderParameters(psiMethod, Collections.<PsiField>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;
}

@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);
Expand All @@ -322,25 +315,29 @@ public PsiClass createBuilderClass(@NotNull PsiClass psiClass, @NotNull PsiAnnot
final AccessorsInfo accessorsInfo = AccessorsInfo.build(psiClass);
final Collection<PsiField> psiFields = getBuilderFields(psiClass, Collections.<PsiField>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<PsiMethod> createMethods(@NotNull PsiClass psiParentClass, @Nullable PsiMethod psiMethod, @NotNull PsiClass psiBuilderClass, @NotNull PsiType psiBuilderType, @NotNull PsiAnnotation psiAnnotation, @NotNull Collection<? extends PsiVariable> psiVariables, PsiSubstitutor builderSubstitutor) {
public Collection<PsiMethod> createMethods(@NotNull PsiClass psiParentClass, @Nullable PsiMethod psiMethod, @NotNull PsiClass psiBuilderClass, @NotNull PsiAnnotation psiAnnotation, @NotNull Collection<? extends PsiVariable> psiVariables, PsiSubstitutor builderSubstitutor) {
final Collection<PsiMethod> methodsIntern = PsiClassUtil.collectClassMethodsIntern(psiBuilderClass);
final Set<String> existedMethodNames = new HashSet<String>(methodsIntern.size());
for (PsiMethod existedMethod : methodsIntern) {
existedMethodNames.add(existedMethod.getName());
}

List<PsiMethod> psiMethods = new ArrayList<PsiMethod>();
final List<PsiMethod> psiMethods = new ArrayList<PsiMethod>();

// 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) {
Expand All @@ -351,9 +348,6 @@ public Collection<PsiMethod> 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);
}
Expand All @@ -369,9 +363,13 @@ public Collection<PsiMethod> 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));
}
Expand Down Expand Up @@ -474,15 +472,16 @@ public Collection<PsiParameter> 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<PsiMethod> classConstructors = PsiClassUtil.collectClassConstructorIntern(parentClass);
Expand All @@ -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
Expand Down

0 comments on commit d652868

Please sign in to comment.