void (List<? extends ClosureParameterInfo> parameters, GrClosableBlock block, PsiSubstitutor substitutor, PsiMethod method, final Project project, final Editor editor) { if (method instanceof ClsMethodImpl) method = ((ClsMethodImpl)method).getSourceMirrorMethod(); assert block.getArrow() == null; if (parameters.isEmpty()) return; StringBuilder buffer = new StringBuilder(); buffer.append("{"); List<PsiType> paramTypes = new ArrayList<>(); for (ClosureParameterInfo parameter : parameters) { final String type = parameter.getType(); final String name = parameter.getName(); if (type != null) { final PsiType fromText = JavaPsiFacade.getElementFactory(project).createTypeFromText(type, method); final PsiType substituted = substitutor.substitute(fromText); paramTypes.add(substituted); buffer.append(substituted.getCanonicalText()).append(" "); } else { buffer.append("def "); } buffer.append(name); buffer.append(", "); } buffer.replace(buffer.length() - 2, buffer.length(), " ->}"); final Document document = editor.getDocument(); final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); assert file != null; final GrClosableBlock closure = GroovyPsiElementFactory.getInstance(project).createClosureFromText(buffer.toString()); final GrClosableBlock templateClosure = (GrClosableBlock)block.replaceWithExpression(closure, false); final TemplateBuilderImpl builder = new TemplateBuilderImpl(templateClosure); int i = 0; for (GrParameter p : templateClosure.getParameters()) { final GrTypeElement typeElement = p.getTypeElementGroovy(); final PsiElement nameIdentifier = p.getNameIdentifierGroovy(); if (typeElement != null) { final TypeConstraint[] typeConstraints = {SupertypeConstraint.create(paramTypes.get(i++))}; final ChooseTypeExpression expression = new ChooseTypeExpression(typeConstraints, PsiManager.getInstance(project), nameIdentifier.getResolveScope()); builder.replaceElement(typeElement, expression); } else { final ChooseTypeExpression expression = new ChooseTypeExpression(TypeConstraint.EMPTY_ARRAY, PsiManager.getInstance(project), nameIdentifier.getResolveScope()); builder.replaceElement(p.getModifierList(), expression); } builder.replaceElement(nameIdentifier, new StringParameterNameExpression(nameIdentifier.getText())); } final GrClosableBlock afterPostprocess = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(templateClosure); final Template template = builder.buildTemplate(); TextRange range = afterPostprocess.getTextRange(); document.deleteString(range.getStartOffset(), range.getEndOffset()); TemplateEditingListener templateListener = new TemplateEditingAdapter() { @Override public void templateFinished(@NotNull Template template, boolean brokenOff) { ApplicationManager.getApplication().runWriteAction(() -> { PsiDocumentManager.getInstance(project).commitDocument(document); final CaretModel caretModel = editor.getCaretModel(); final int offset = caretModel.getOffset(); GrClosableBlock block1 = PsiTreeUtil.findElementOfClassAtOffset(file, offset - 1, GrClosableBlock.class, false); if (block1 != null) { final PsiElement arrow = block1.getArrow(); if (arrow != null) { caretModel.moveToOffset(arrow.getTextRange().getEndOffset()); } // fix space before closure lbrace final TextRange range1 = block1.getTextRange(); CodeStyleManager.getInstance(project).reformatRange(block1.getParent(), range1.getStartOffset() - 1, range1.getEndOffset(), true); } }); } }; TemplateManager manager = TemplateManager.getInstance(project); manager.startTemplate(editor, template, templateListener); }