package de.plushnikov.intellij.plugin.processor.handler.singular; import com.intellij.openapi.project.Project; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiSubstitutor; import com.intellij.psi.PsiType; import com.intellij.psi.PsiVariable; import de.plushnikov.intellij.plugin.processor.field.AccessorsInfo; import de.plushnikov.intellij.plugin.psi.LombokLightFieldBuilder; import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder; import de.plushnikov.intellij.plugin.util.PsiTypeUtil; import org.jetbrains.annotations.NotNull; import java.text.MessageFormat; import java.util.List; class SingularGuavaMapHandler extends SingularMapHandler { private static final String LOMBOK_KEY = "key"; private static final String LOMBOK_VALUE = "value"; private final boolean sortedCollection; SingularGuavaMapHandler(String guavaQualifiedName, boolean sortedCollection, boolean shouldGenerateFullBodyBlock) { super(guavaQualifiedName, shouldGenerateFullBodyBlock); this.sortedCollection = sortedCollection; } public void addBuilderField(@NotNull List<PsiField> fields, @NotNull PsiVariable psiVariable, @NotNull PsiClass innerClass, @NotNull AccessorsInfo accessorsInfo, @NotNull PsiSubstitutor substitutor) { final String fieldName = accessorsInfo.removePrefix(psiVariable.getName()); final LombokLightFieldBuilder fieldBuilder = new LombokLightFieldBuilder(psiVariable.getManager(), fieldName, getBuilderFieldType(substitutor.substitute(psiVariable.getType()), psiVariable.getProject())) .withModifier(PsiModifier.PRIVATE) .withNavigationElement(psiVariable) .withContainingClass(innerClass); fields.add(fieldBuilder); } @NotNull protected PsiType getBuilderFieldType(@NotNull PsiType psiFieldType, @NotNull Project project) { final PsiManager psiManager = PsiManager.getInstance(project); final PsiType keyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, CommonClassNames.JAVA_UTIL_MAP, 0); final PsiType valueType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, CommonClassNames.JAVA_UTIL_MAP, 1); return PsiTypeUtil.createCollectionType(psiManager, collectionQualifiedName + ".Builder", keyType, valueType); } protected void addOneMethodParameter(@NotNull LombokLightMethodBuilder methodBuilder, @NotNull PsiType psiFieldType, @NotNull String singularName) { final PsiManager psiManager = methodBuilder.getManager(); final PsiType keyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, CommonClassNames.JAVA_UTIL_MAP, 0); final PsiType valueType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, CommonClassNames.JAVA_UTIL_MAP, 1); methodBuilder.withParameter(LOMBOK_KEY, keyType); methodBuilder.withParameter(LOMBOK_VALUE, valueType); } protected String getClearMethodBody(String psiFieldName, boolean fluentBuilder) { final String codeBlockTemplate = "this.{0} = null;\n {1}"; return MessageFormat.format(codeBlockTemplate, psiFieldName, fluentBuilder ? "\nreturn this;" : ""); } protected String getOneMethodBody(@NotNull String singularName, @NotNull String psiFieldName, @NotNull PsiType psiFieldType, @NotNull PsiManager psiManager, boolean fluentBuilder) { final String codeBlockTemplate = "if (this.{0} == null) this.{0} = {2}.{3}; \n" + "this.{0}.put(" + LOMBOK_KEY + ", " + LOMBOK_VALUE + ");{4}"; return MessageFormat.format(codeBlockTemplate, psiFieldName, singularName, collectionQualifiedName, sortedCollection ? "naturalOrder()" : "builder()", fluentBuilder ? "\nreturn this;" : ""); } protected String getAllMethodBody(@NotNull String singularName, @NotNull PsiType psiFieldType, @NotNull PsiManager psiManager, boolean fluentBuilder) { final String codeBlockTemplate = "if (this.{0} == null) this.{0} = {1}.{2}; \n" + "this.{0}.putAll({0});{3}"; return MessageFormat.format(codeBlockTemplate, singularName, collectionQualifiedName, sortedCollection ? "naturalOrder()" : "builder()", fluentBuilder ? "\nreturn this;" : ""); } @Override public void appendBuildPrepare(@NotNull StringBuilder buildMethodCode, @NotNull PsiVariable psiVariable, @NotNull String fieldName) { final PsiManager psiManager = psiVariable.getManager(); final PsiType psiFieldType = psiVariable.getType(); final PsiType keyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, CommonClassNames.JAVA_UTIL_MAP, 0); final PsiType valueType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, CommonClassNames.JAVA_UTIL_MAP, 1); buildMethodCode.append(MessageFormat.format( "{3}<{1}, {2}> {0} = " + "this.{0} == null ? " + "{3}.<{1}, {2}>of() : " + "this.{0}.build();\n", fieldName, keyType.getCanonicalText(false), valueType.getCanonicalText(false), collectionQualifiedName)); } }