@Nullable public static PsiClass createSubclassGroovy( final GrTypeDefinition psiClass, final PsiDirectory targetDirectory, final String className) { final Project project = psiClass.getProject(); final Ref<GrTypeDefinition> targetClass = new Ref<GrTypeDefinition>(); new WriteCommandAction(project, getTitle(psiClass), getTitle(psiClass)) { @Override protected void run(Result result) throws Throwable { IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace(); final GrTypeParameterList oldTypeParameterList = psiClass.getTypeParameterList(); try { targetClass.set( CreateClassActionBase.createClassByType( targetDirectory, className, PsiManager.getInstance(project), psiClass, NewGroovyClassAction.GROOVY_CLASS)); } catch (final IncorrectOperationException e) { ApplicationManager.getApplication() .invokeLater( new Runnable() { @Override public void run() { Messages.showErrorDialog( project, CodeInsightBundle.message( "intention.error.cannot.create.class.message", className) + "\n" + e.getLocalizedMessage(), CodeInsightBundle.message("intention.error.cannot.create.class.title")); } }); return; } startTemplate(oldTypeParameterList, project, psiClass, targetClass.get(), false); GrReferenceAdjuster.shortenReferences(targetClass.get()); } }.execute(); if (targetClass.get() == null) return null; if (!ApplicationManager.getApplication().isUnitTestMode() && !psiClass.hasTypeParameters()) { final Editor editor = CodeInsightUtil.positionCursor( project, targetClass.get().getContainingFile(), targetClass.get().getLBrace()); if (editor == null) return targetClass.get(); chooseAndImplement(psiClass, project, targetClass.get(), editor); } return targetClass.get(); }
private static void startTemplate( GrTypeParameterList oldTypeParameterList, final Project project, final GrTypeDefinition psiClass, final GrTypeDefinition targetClass, boolean includeClassName) { PsiElementFactory jfactory = JavaPsiFacade.getElementFactory(project); final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(project); GrCodeReferenceElement ref = elementFactory.createCodeReferenceElementFromClass(psiClass); try { if (psiClass.isInterface()) { GrImplementsClause clause = targetClass.getImplementsClause(); if (clause == null) { clause = (GrImplementsClause) targetClass.addAfter( elementFactory.createImplementsClause(), targetClass.getNameIdentifierGroovy()); } ref = (GrCodeReferenceElement) clause.add(ref); } else { GrExtendsClause clause = targetClass.getExtendsClause(); if (clause == null) { clause = (GrExtendsClause) targetClass.addAfter( elementFactory.createExtendsClause(), targetClass.getNameIdentifierGroovy()); } ref = (GrCodeReferenceElement) clause.add(ref); } if (psiClass.hasTypeParameters() || includeClassName) { final Editor editor = CodeInsightUtil.positionCursor( project, targetClass.getContainingFile(), targetClass.getLBrace()); final TemplateBuilderImpl templateBuilder = editor == null || ApplicationManager.getApplication().isUnitTestMode() ? null : (TemplateBuilderImpl) TemplateBuilderFactory.getInstance().createTemplateBuilder(targetClass); if (includeClassName && templateBuilder != null) { templateBuilder.replaceElement(targetClass.getNameIdentifier(), targetClass.getName()); } if (oldTypeParameterList != null) { for (PsiTypeParameter parameter : oldTypeParameterList.getTypeParameters()) { final PsiElement param = ref.getTypeArgumentList() .add(elementFactory.createTypeElement(jfactory.createType(parameter))); if (templateBuilder != null) { templateBuilder.replaceElement(param, param.getText()); } } } final GrTypeParameterList typeParameterList = targetClass.getTypeParameterList(); assert typeParameterList != null; typeParameterList.replace(oldTypeParameterList); if (templateBuilder != null) { templateBuilder.setEndVariableBefore(ref); final Template template = templateBuilder.buildTemplate(); template.addEndVariable(); final PsiFile containingFile = targetClass.getContainingFile(); PsiDocumentManager.getInstance(project) .doPostponedOperationsAndUnblockDocument(editor.getDocument()); final TextRange textRange = targetClass.getTextRange(); final int startClassOffset = textRange.getStartOffset(); editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset()); CreateFromUsageBaseFix.startTemplate( editor, template, project, new TemplateEditingAdapter() { @Override public void templateFinished(Template template, boolean brokenOff) { chooseAndImplement( psiClass, project, PsiTreeUtil.getParentOfType( containingFile.findElementAt(startClassOffset), GrTypeDefinition.class), editor); } }, getTitle(psiClass)); } } } catch (IncorrectOperationException e) { LOG.error(e); } }