package com.jetbrains.lang.dart.ide.surroundWith.statement; import com.intellij.lang.ASTNode; import com.intellij.lang.surroundWith.Surrounder; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiParserFacade; import com.intellij.util.IncorrectOperationException; import com.jetbrains.lang.dart.util.DartElementGenerator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author: Fedor.Korotkov */ public abstract class DartStatementSurrounder implements Surrounder { public boolean isApplicable(@NotNull PsiElement[] elements) { return true; } @Nullable protected PsiElement createSurrounder(@NotNull Project project) { return DartElementGenerator.createStatementFromText( project, getTemplateText() ); } @Nullable public TextRange surroundElements(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement[] elements) throws IncorrectOperationException { PsiElement parent = elements[0].getParent(); PsiElement surrounder = createSurrounder(project); if (surrounder == null) { throw new IncorrectOperationException("Can't surround statements!"); } surrounder = parent.addBefore(surrounder, elements[0]); final PsiElement elementToAdd = findElementToAdd(surrounder); if (elementToAdd == null) { parent.deleteChildRange(surrounder, surrounder); throw new IncorrectOperationException("Can't surround statements!"); } for (PsiElement element : elements) { ASTNode node = element.getNode(); final ASTNode copyNode = node.copyElement(); parent.getNode().removeChild(node); elementToAdd.getNode().addChild(copyNode); } afterAdd(elementToAdd); int endOffset = cleanUpAndGetPlaceForCaret(surrounder); return TextRange.create(endOffset, endOffset); } @SuppressWarnings("MethodMayBeStatic") protected void afterAdd(PsiElement elementToAdd) { final PsiElement newLineNode = PsiParserFacade.SERVICE.getInstance(elementToAdd.getProject()).createWhiteSpaceFromText("\n"); elementToAdd.add(newLineNode); } protected abstract String getTemplateText(); @Nullable protected abstract PsiElement findElementToAdd(@NotNull final PsiElement surrounder); protected abstract int cleanUpAndGetPlaceForCaret(@NotNull PsiElement surrounder); }