package de.plushnikov.intellij.plugin.processor.handler.singular; import com.intellij.openapi.project.Project; 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 SingularGuavaTableHandler extends SingularMapHandler { private static final String COM_GOOGLE_COMMON_COLLECT_TABLE = "com.google.common.collect.Table"; private static final String LOMBOK_ROW_KEY = "rowKey"; private static final String LOMBOK_COLUMN_KEY = "columnKey"; private static final String LOMBOK_VALUE = "value"; private final boolean sortedCollection; SingularGuavaTableHandler(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 rowKeyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 0); final PsiType columnKeyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 1); final PsiType valueType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 2); return PsiTypeUtil.createCollectionType(psiManager, collectionQualifiedName + ".Builder", rowKeyType, columnKeyType, valueType); } protected void addOneMethodParameter(@NotNull LombokLightMethodBuilder methodBuilder, @NotNull PsiType psiFieldType, @NotNull String singularName) { final PsiManager psiManager = methodBuilder.getManager(); final PsiType rowKeyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 0); final PsiType columnKeyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 1); final PsiType valueType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 2); methodBuilder.withParameter(LOMBOK_ROW_KEY, rowKeyType); methodBuilder.withParameter(LOMBOK_COLUMN_KEY, columnKeyType); methodBuilder.withParameter(LOMBOK_VALUE, valueType); } protected void addAllMethodParameter(@NotNull LombokLightMethodBuilder methodBuilder, @NotNull PsiType psiFieldType, @NotNull String singularName) { final PsiManager psiManager = methodBuilder.getManager(); final PsiType rowKeyType = PsiTypeUtil.extractAllElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 0); final PsiType columnKeyType = PsiTypeUtil.extractAllElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 1); final PsiType valueType = PsiTypeUtil.extractAllElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 2); final PsiType collectionType = PsiTypeUtil.createCollectionType(psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, rowKeyType, columnKeyType, valueType); methodBuilder.withParameter(singularName, collectionType); } 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_ROW_KEY + ", " + LOMBOK_COLUMN_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 rowKeyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 0); final PsiType columnKeyType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 1); final PsiType valueType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager, COM_GOOGLE_COMMON_COLLECT_TABLE, 2); buildMethodCode.append(MessageFormat.format( "{4}<{1}, {2}, {3}> {0} = " + "this.{0} == null ? " + "{4}.<{1}, {2}, {3}>of() : " + "this.{0}.build();\n", fieldName, rowKeyType.getCanonicalText(false), columnKeyType.getCanonicalText(false), valueType.getCanonicalText(false), collectionQualifiedName)); } }