package de.plushnikov.intellij.plugin.processor.handler.singular; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiType; import com.intellij.psi.PsiVariable; import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder; import de.plushnikov.intellij.plugin.util.PsiTypeUtil; import org.jetbrains.annotations.NotNull; import java.text.MessageFormat; class SingularCollectionHandler extends AbstractSingularHandler { SingularCollectionHandler(String qualifiedName, boolean shouldGenerateFullBodyBlock) { super(qualifiedName, shouldGenerateFullBodyBlock); } protected void addOneMethodParameter(@NotNull LombokLightMethodBuilder methodBuilder, @NotNull PsiType psiFieldType, @NotNull String singularName) { final PsiType oneElementType = PsiTypeUtil.extractOneElementType(psiFieldType, methodBuilder.getManager()); methodBuilder.withParameter(singularName, oneElementType); } protected void addAllMethodParameter(@NotNull LombokLightMethodBuilder methodBuilder, @NotNull PsiType psiFieldType, @NotNull String singularName) { final PsiManager psiManager = methodBuilder.getManager(); final PsiType elementType = PsiTypeUtil.extractAllElementType(psiFieldType, psiManager); final PsiType collectionType = PsiTypeUtil.createCollectionType(psiManager, CommonClassNames.JAVA_UTIL_COLLECTION, elementType); methodBuilder.withParameter(singularName, collectionType); } protected String getClearMethodBody(String psiFieldName, boolean fluentBuilder) { final String codeBlockTemplate = "if (this.{0} != null) \n this.{0}.clear();\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} = new java.util.ArrayList<{3}>(); \n" + "this.{0}.add({1});{2}"; final PsiType oneElementType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager); return MessageFormat.format(codeBlockTemplate, psiFieldName, singularName, fluentBuilder ? "\nreturn this;" : "", oneElementType.getCanonicalText(false)); } protected String getAllMethodBody(@NotNull String singularName, @NotNull PsiType psiFieldType, @NotNull PsiManager psiManager, boolean fluentBuilder) { final String codeBlockTemplate = "if (this.{0} == null) this.{0} = new java.util.ArrayList<{2}>(); \n" + "this.{0}.addAll({0});{1}"; final PsiType oneElementType = PsiTypeUtil.extractOneElementType(psiFieldType, psiManager); return MessageFormat.format(codeBlockTemplate, singularName, fluentBuilder ? "\nreturn this;" : "", oneElementType.getCanonicalText(false)); } @Override public void appendBuildPrepare(@NotNull StringBuilder buildMethodCode, @NotNull PsiVariable psiVariable, @NotNull String fieldName) { final PsiManager psiManager = psiVariable.getManager(); final PsiType elementType = PsiTypeUtil.extractOneElementType(psiVariable.getType(), psiManager); final String selectedFormat; if (SingularCollectionClassNames.JAVA_UTIL_NAVIGABLE_SET.equals(collectionQualifiedName)) { selectedFormat = "{2}<{1}> {0} = new java.util.TreeSet<{1}>();\n" + "if (this.{0} != null) {0}.addAll(this.{0});\n" + "{0} = java.util.Collections.unmodifiableNavigableSet({0});\n"; } else if (SingularCollectionClassNames.JAVA_UTIL_SORTED_SET.equals(collectionQualifiedName)) { selectedFormat = "{2}<{1}> {0} = new java.util.TreeSet<{1}>();\n" + "if (this.{0} != null) {0}.addAll(this.{0});\n" + "{0} = java.util.Collections.unmodifiableSortedSet({0});\n"; } else if (SingularCollectionClassNames.JAVA_UTIL_SET.equals(collectionQualifiedName)) { selectedFormat = "{2}<{1}> {0};\n" + "switch (this.{0} == null ? 0 : this.{0}.size()) '{'\n" + " case 0: \n" + " {0} = java.util.Collections.emptySet();\n" + " break;\n" + " case 1: \n" + " {0} = java.util.Collections.singleton(this.{0}.get(0));\n" + " break;\n" + " default: \n" + " {0} = new java.util.LinkedHashSet<{1}>(this.{0}.size() < 1073741824 ? 1 + this.{0}.size() + (this.{0}.size() - 3) / 3 : java.lang.Integer.MAX_VALUE);\n" + " {0}.addAll(this.{0});\n" + " {0} = java.util.Collections.unmodifiableSet({0});\n" + "'}'\n"; } else { selectedFormat = "{2}<{1}> {0};\n" + "switch (this.{0} == null ? 0 : this.{0}.size()) '{'\n" + "case 0: \n" + " {0} = java.util.Collections.emptyList();\n" + " break;\n" + "case 1: \n" + " {0} = java.util.Collections.singletonList(this.{0}.get(0));\n" + " break;\n" + "default: \n" + " {0} = java.util.Collections.unmodifiableList(new java.util.ArrayList<{1}>(this.{0}));\n" + "'}'\n"; } buildMethodCode.append(MessageFormat.format(selectedFormat, fieldName, elementType.getCanonicalText(false), collectionQualifiedName)); } }