PsiMethod (@Nullable PsiMethod constructor, PsiClass containingClass, PsiTypeParameter[] params, PsiJavaCodeReferenceElement reference) { final StringBuilder buf = new StringBuilder(); final String modifier = VisibilityUtil.getVisibilityModifier(constructor != null ? constructor.getModifierList() : containingClass.getModifierList()); if (!PsiModifier.PACKAGE_LOCAL.equals(modifier)) { buf.append(modifier); buf.append(" "); } buf.append("static "); buf.append("<"); //it's possible that constructor type parameters and class type parameters are same named: //it's important that class type parameters names are preserved(they are first in the list), //though constructor parameters would be renamed in case of conflicts final UniqueNameGenerator generator = new UniqueNameGenerator(); buf.append(StringUtil.join(params, psiTypeParameter -> { String extendsList = ""; if (psiTypeParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { final PsiClassType[] extendsListTypes = psiTypeParameter.getExtendsListTypes(); if (extendsListTypes.length > 0) { final Function<PsiClassType, String> canonicalTypePresentationFun = type -> type.getCanonicalText(); extendsList = " extends " + StringUtil.join(extendsListTypes, canonicalTypePresentationFun, "&"); } } return generator.generateUniqueName(psiTypeParameter.getName()) + extendsList; }, ", ")); buf.append(">"); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(containingClass.getProject()); String qualifiedName = containingClass.getQualifiedName(); PsiElement qualifier = reference != null ? reference.getQualifier() : null; if (qualifier instanceof PsiJavaCodeReferenceElement) { final JavaResolveResult resolveResult = ((PsiJavaCodeReferenceElement)qualifier).advancedResolve(false); final PsiElement element = resolveResult.getElement(); if (element instanceof PsiClass) { final String outerClassSubstitutedQName = elementFactory.createType((PsiClass)element, resolveResult.getSubstitutor()).getInternalCanonicalText(); qualifiedName = outerClassSubstitutedQName + "." + containingClass.getName(); } } else if (reference != null && qualifier == null && containingClass.getContainingClass() != null) { qualifiedName = null; } buf.append(qualifiedName != null ? qualifiedName : containingClass.getName()); final PsiTypeParameter[] parameters = containingClass.getTypeParameters(); buf.append("<"); buf.append(StringUtil.join(parameters, psiTypeParameter -> psiTypeParameter.getName(), ", ")); buf.append("> "); String staticFactoryName = "staticFactory"; final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(containingClass.getProject()); staticFactoryName = styleManager.suggestUniqueVariableName(staticFactoryName, containingClass, false); buf.append(staticFactoryName); if (constructor == null) { buf.append("()"); } else { buf.append("(").append(StringUtil.join(constructor.getParameterList().getParameters(), new Function<PsiParameter, String>() { int myIdx; @Override public String fun(PsiParameter psiParameter) { return psiParameter.getType().getCanonicalText() + " p" + myIdx++; } }, ",")).append(")"); PsiClassType[] types = constructor.getThrowsList().getReferencedTypes(); if (types.length > 0) { buf.append("throws ").append(StringUtil.join(types, type -> type.getCanonicalText(), ", ")); } } buf.append("{}"); try { return elementFactory.createMethodFromText(buf.toString(), constructor != null ? constructor : containingClass); } catch (IncorrectOperationException e) { return null; } }