void (@NotNull PsiRecordHeader header, @NotNull TemplateBuilder builder, @NotNull PsiSubstitutor substitutor, @NotNull PsiCaseLabelElement @NotNull [] elements) { final PsiManager psiManager = header.getManager(); final Project project = psiManager.getProject(); PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); GlobalSearchScope resolveScope = header.getResolveScope(); GuessTypeParameters guesser = new GuessTypeParameters(project, JavaPsiFacade.getElementFactory(project), builder, substitutor); final PsiClass containingClass = header.getContainingClass(); if (containingClass == null) return; class ComponentData { final PsiType myType; final String[] myNames; ComponentData(PsiType type, String[] names) { myType = type; myNames = names; } @Override public String toString() { return myType.getCanonicalText() + " " + myNames[0]; } } List<ComponentData> components = new ArrayList<>(); //255 is the maximum number of record components for (int i = 0; i < Math.min(elements.length, 255); i++) { PsiCaseLabelElement element = elements[i]; PsiType type = element instanceof PsiExpression expression ? CommonJavaRefactoringUtil.getTypeByExpression(expression) : JavaPsiPatternUtil.getPatternType(element); @NonNls String[] names = suggestVariableName(project, element, type).names; if (names.length == 0) { names = new String[]{"c" + i}; } type = CreateFromUsageUtils.getParameterTypeByArgumentType(type, psiManager, resolveScope); components.add(new ComponentData(type, names)); } PsiRecordHeader newHeader = factory.createRecordHeaderFromText(StringUtil.join(components, ", "), containingClass); PsiRecordHeader replacedHeader = (PsiRecordHeader)header.replace(newHeader); PsiRecordComponent[] recordComponents = replacedHeader.getRecordComponents(); assert recordComponents.length == components.size(); for (int i = 0; i < recordComponents.length; i++) { PsiRecordComponent component = recordComponents[i]; ComponentData data = components.get(i); int kind = TypeConversionUtil.isPrimitiveAndNotNull(data.myType) ? ExpectedTypeInfo.TYPE_STRICTLY : ExpectedTypeInfo.TYPE_OR_SUPERTYPE; ExpectedTypeInfo info = ExpectedTypesProvider.createInfo(data.myType, kind, data.myType, TailTypes.noneType()); PsiElement context = PsiTreeUtil.getParentOfType(elements[i], PsiClass.class, PsiMethod.class); guesser.setupTypeElement(Objects.requireNonNull(component.getTypeElement()), new ExpectedTypeInfo[]{info}, context, containingClass); Expression expression = new CreateFromUsageUtils.ParameterNameExpression(data.myNames); builder.replaceElement(Objects.requireNonNull(component.getNameIdentifier()), expression); } }