PsiMethod (@NotNull Project project, @NotNull PsiClass containingClass, @Nullable PsiMethod constructor, @NotNull String defaultFactoryName) { PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); PsiClassType type = factory.createType(containingClass, PsiSubstitutor.EMPTY); PsiMethod factoryMethod = factory.createMethod(defaultFactoryName, type); if (constructor != null) { factoryMethod.getParameterList().replace(constructor.getParameterList()); factoryMethod.getThrowsList().replace(constructor.getThrowsList()); } Collection<String> names = new HashSet<>(); for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(constructor != null ? constructor : containingClass)) { if (!names.contains(typeParameter.getName())) { //Otherwise type parameter is hidden in the constructor names.add(typeParameter.getName()); Objects.requireNonNull(factoryMethod.getTypeParameterList()).addAfter(typeParameter, null); } } PsiReturnStatement returnStatement = (PsiReturnStatement)factory.createStatementFromText("return new A();", null); PsiNewExpression newExpression = (PsiNewExpression)Objects.requireNonNull(returnStatement.getReturnValue()); PsiJavaCodeReferenceElement classRef = factory.createReferenceElementByType(type); Objects.requireNonNull(newExpression.getClassReference()).replace(classRef); PsiExpressionList argumentList = Objects.requireNonNull(newExpression.getArgumentList()); PsiParameter[] params = factoryMethod.getParameterList().getParameters(); for (PsiParameter parameter : params) { PsiExpression paramRef = factory.createExpressionFromText(parameter.getName(), null); argumentList.add(paramRef); } Objects.requireNonNull(factoryMethod.getBody()).add(returnStatement); PsiMember visibilityOwner = constructor == null ? containingClass : constructor; PsiUtil.setModifierProperty(factoryMethod, VisibilityUtil.getVisibilityModifier(visibilityOwner.getModifierList()), true); boolean inner = containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC); if (!inner) { PsiUtil.setModifierProperty(factoryMethod, PsiModifier.STATIC, true); } return (PsiMethod)CodeStyleManager.getInstance(project).reformat(factoryMethod); }