implementationClass="org.jetbrains.javafx.lang.psi.impl.resolve.JavaFxReferenceElementManipulator"/>
<lang.surroundDescriptor language="JavaFx"
implementationClass="org.jetbrains.javafx.refactoring.surround.JavaFxExpressionSurroundDescriptor"/>
+ <lang.surroundDescriptor language="JavaFx"
+ implementationClass="org.jetbrains.javafx.refactoring.surround.JavaFxStatementSurroundDescriptor"/>
<lang.findUsagesProvider language="JavaFx" implementationClass="org.jetbrains.javafx.findUsages.JavaFxFindUsagesProvider"/>
<lang.namesValidator language="JavaFx" implementationClass="org.jetbrains.javafx.refactoring.rename.JavaFxNamesValidator"/>
* Time: 18:14:11
*/
public interface JavaFxIfExpression extends JavaFxValueExpression {
+ @Nullable
+ JavaFxExpression getCondition();
+
@Nullable
JavaFxExpression getIfBranch();
super(node);
}
+ @Override
+ public JavaFxExpression getCondition() {
+ return (JavaFxExpression)childToPsi(JavaFxElementTypes.EXPRESSIONS, 0);
+ }
+
@Nullable
@Override
public JavaFxExpression getIfBranch() {
*/
package org.jetbrains.javafx.refactoring;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+import org.jetbrains.javafx.lang.parser.JavaFxElementTypes;
+import org.jetbrains.javafx.lang.psi.JavaFxBlockExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxFile;
import org.jetbrains.javafx.lang.psi.JavaFxValueExpression;
+import java.util.ArrayList;
+
/**
* Created by IntelliJ IDEA.
*
- * @author: Alexey.Ivanov
+ * @author Alexey.Ivanov
*/
public class JavaFxRefactoringUtil {
private JavaFxRefactoringUtil() {
}
@Nullable
- public static JavaFxValueExpression findExpressionInRange(final PsiFile file, final int startOffset, final int endOffset) {
+ public static JavaFxValueExpression findValueExpressionInRange(final PsiFile file, final int startOffset, final int endOffset) {
if (startOffset > endOffset) {
return null;
}
}
return expression;
}
+
+ @NotNull
+ public static PsiElement[] findExpressionsInRange(final PsiFile file, int startOffset, int endOffset) {
+ if (startOffset > endOffset) {
+ return JavaFxExpression.EMPTY_ARRAY;
+ }
+ PsiElement element1 = file.findElementAt(startOffset);
+ PsiElement element2 = file.findElementAt(endOffset - 1);
+ if (element1 instanceof PsiWhiteSpace) {
+ startOffset = element1.getTextRange().getEndOffset();
+ element1 = file.findElementAt(startOffset);
+ }
+ if (element2 instanceof PsiWhiteSpace) {
+ endOffset = element2.getTextRange().getStartOffset();
+ element2 = file.findElementAt(endOffset - 1);
+ }
+ if (element1 == null || element2 == null || element1.getNode().getElementType() == JavaFxElementTypes.SEMICOLON) {
+ return JavaFxExpression.EMPTY_ARRAY;
+ }
+
+ final PsiElement commonParent = PsiTreeUtil.findCommonParent(element1, element2);
+ if (commonParent == null) {
+ return JavaFxExpression.EMPTY_ARRAY;
+ }
+ PsiElement parent =
+ PsiTreeUtil.getParentOfType(commonParent, JavaFxExpression.class, false, JavaFxBlockExpression.class, JavaFxFile.class);
+ if (parent == null) {
+ if (commonParent instanceof JavaFxFile) {
+ parent = commonParent;
+ }
+ else {
+ return JavaFxExpression.EMPTY_ARRAY;
+ }
+ }
+
+ if (!parent.equals(element1)) {
+ while (!parent.equals(element1.getParent())) {
+ element1 = element1.getParent();
+ }
+ }
+ if (startOffset != element1.getTextRange().getStartOffset()) {
+ return JavaFxExpression.EMPTY_ARRAY;
+ }
+
+ if (!parent.equals(element2)) {
+ while (!parent.equals(element2.getParent())) {
+ element2 = element2.getParent();
+ }
+ }
+ if (endOffset != element2.getTextRange().getEndOffset()) {
+ return JavaFxExpression.EMPTY_ARRAY;
+ }
+
+ final ASTNode node = parent.getNode();
+ if (node == null) {
+ return JavaFxExpression.EMPTY_ARRAY;
+ }
+ ASTNode astNode = node.getFirstChildNode();
+ final ArrayList<PsiElement> array = new ArrayList<PsiElement>();
+ boolean flag = false;
+ while (astNode != null) {
+ final PsiElement child = astNode.getPsi();
+ astNode = astNode.getTreeNext();
+ if (child == null) {
+ break;
+ }
+ if (child.equals(element1)) {
+ flag = true;
+ }
+ if (flag && !(child instanceof PsiWhiteSpace)) {
+ array.add(child);
+ }
+ if (child.equals(element2)) {
+ break;
+ }
+ }
+
+ for (PsiElement element : array) {
+ if (!(element instanceof JavaFxExpression ||
+ element instanceof PsiWhiteSpace ||
+ element instanceof PsiComment ||
+ element.getNode().getElementType() == JavaFxTokenTypes.SEMICOLON)) {
+ return JavaFxExpression.EMPTY_ARRAY;
+ }
+ }
+ return array.toArray(new PsiElement[array.size()]);
+ }
}
@NotNull
@Override
public PsiElement[] getElementsToSurround(PsiFile file, int startOffset, int endOffset) {
- final JavaFxValueExpression expression = JavaFxRefactoringUtil.findExpressionInRange(file, startOffset, endOffset);
+ final JavaFxValueExpression expression = JavaFxRefactoringUtil.findValueExpressionInRange(file, startOffset, endOffset);
+ if (expression == null) {
+ return PsiElement.EMPTY_ARRAY;
+ }
return new PsiElement[]{expression};
}
--- /dev/null
+package org.jetbrains.javafx.refactoring.surround;
+
+import com.intellij.lang.surroundWith.SurroundDescriptor;
+import com.intellij.lang.surroundWith.Surrounder;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.refactoring.JavaFxRefactoringUtil;
+import org.jetbrains.javafx.refactoring.surround.surrounders.statements.JavaFxWithIfElseSurrounder;
+import org.jetbrains.javafx.refactoring.surround.surrounders.statements.JavaFxWithIfSurrounder;
+import org.jetbrains.javafx.refactoring.surround.surrounders.statements.JavaFxWithWhileSurrounder;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author Alexey.Ivanov
+ */
+public class JavaFxStatementSurroundDescriptor implements SurroundDescriptor {
+ private static final Surrounder[] SURROUNDERS =
+ {new JavaFxWithIfSurrounder(), new JavaFxWithIfElseSurrounder(), new JavaFxWithWhileSurrounder()};
+
+ @NotNull
+ @Override
+ public PsiElement[] getElementsToSurround(final PsiFile file, final int startOffset, final int endOffset) {
+ final PsiElement[] expressions = JavaFxRefactoringUtil.findExpressionsInRange(file, startOffset, endOffset);
+ if (expressions.length == 0) {
+ return PsiElement.EMPTY_ARRAY;
+ }
+ return expressions;
+ }
+
+ @NotNull
+ @Override
+ public Surrounder[] getSurrounders() {
+ return SURROUNDERS;
+ }
+}
* Created by IntelliJ IDEA.
* @author: Alexey.Ivanov
*/
-public class JavaFxWithAsSurrounder extends JavaFxExpressionSurrounder {
+public class JavaFxWithAsSurrounder extends JavaFxWithExpressionSurrounder {
@Override
protected boolean isApplicable(JavaFxValueExpression element) {
return true;
* Created by IntelliJ IDEA.
* @author: Alexey.Ivanov
*/
-public abstract class JavaFxExpressionSurrounder implements Surrounder {
- private static final Logger LOG = Logger.getInstance("#org.jetbrains.javafx.refactoring.surround.surrounders.expressions.JavaFxExpressionSurrounder");
+public abstract class JavaFxWithExpressionSurrounder implements Surrounder {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.javafx.refactoring.surround.surrounders.expressions.JavaFxWithExpressionSurrounder");
@Override
public boolean isApplicable(@NotNull PsiElement[] elements) {
* Created by IntelliJ IDEA.
* @author: Alexey.Ivanov
*/
-public class JavaFxWithNotInstanceofSurrounder extends JavaFxExpressionSurrounder {
+public class JavaFxWithNotInstanceofSurrounder extends JavaFxWithExpressionSurrounder {
@Override
protected boolean isApplicable(JavaFxValueExpression element) {
return true;
*
* @author: Alexey.Ivanov
*/
-public class JavaFxWithNotSurrounder extends JavaFxExpressionSurrounder {
+public class JavaFxWithNotSurrounder extends JavaFxWithExpressionSurrounder {
@Override
protected boolean isApplicable(final JavaFxValueExpression element) {
return JavaFxPrimitiveType.BOOLEAN.equals(element.getType());
*
* @author: Alexey.Ivanov
*/
-public class JavaFxWithParenthesesSurrounder extends JavaFxExpressionSurrounder {
+public class JavaFxWithParenthesesSurrounder extends JavaFxWithExpressionSurrounder {
@Override
protected boolean isApplicable(final JavaFxValueExpression element) {
return true;
--- /dev/null
+package org.jetbrains.javafx.refactoring.surround.surrounders.statements;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.CodeInsightUtilBase;
+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.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.lang.psi.JavaFxBlockExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxIfExpression;
+import org.jetbrains.javafx.refactoring.JavaFxChangeUtil;
+
+/**
+ * Created by IntelliJ IDEA.
+ * @author Alexey.Ivanov
+ */
+public class JavaFxWithIfElseSurrounder extends JavaFxWithStatementSurrounder {
+ @Override
+ public String getTemplateDescription() {
+ return CodeInsightBundle.message("surround.with.ifelse.template");
+ }
+
+ @Override
+ public TextRange surroundElements(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiElement[] elements)
+ throws IncorrectOperationException {
+ JavaFxExpression ifExpression = JavaFxChangeUtil.createExpressionFromText(project, "if (true) {\n\n}\nelse {\n}");
+ final PsiElement parent = elements[0].getParent();
+ if (ifExpression instanceof JavaFxIfExpression) {
+ final JavaFxBlockExpression blockExpression = (JavaFxBlockExpression)((JavaFxIfExpression)ifExpression).getIfBranch();
+ assert blockExpression != null;
+ blockExpression.addRangeAfter(elements[0], elements[elements.length - 1], blockExpression.getFirstChild().getNextSibling());
+ ifExpression = (JavaFxExpression)parent.addBefore(ifExpression, elements[0]);
+ parent.deleteChildRange(elements[0], elements[elements.length - 1]);
+ ifExpression = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(ifExpression);
+ if (ifExpression != null) {
+ return ((JavaFxIfExpression)ifExpression).getCondition().getTextRange();
+ }
+ }
+ return null;
+ }
+}
--- /dev/null
+package org.jetbrains.javafx.refactoring.surround.surrounders.statements;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.CodeInsightUtilBase;
+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.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.lang.psi.JavaFxBlockExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxIfExpression;
+import org.jetbrains.javafx.refactoring.JavaFxChangeUtil;
+
+/**
+ * Created by IntelliJ IDEA.
+ * @author Alexey.Ivanov
+ */
+public class JavaFxWithIfSurrounder extends JavaFxWithStatementSurrounder {
+ @Override
+ public String getTemplateDescription() {
+ return CodeInsightBundle.message("surround.with.if.template");
+ }
+
+ @Override
+ public TextRange surroundElements(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiElement[] elements)
+ throws IncorrectOperationException {
+ JavaFxExpression ifExpression = JavaFxChangeUtil.createExpressionFromText(project, "if (true) {\n\n}");
+ final PsiElement parent = elements[0].getParent();
+ if (ifExpression instanceof JavaFxIfExpression) {
+ final JavaFxBlockExpression blockExpression = (JavaFxBlockExpression)((JavaFxIfExpression)ifExpression).getIfBranch();
+ assert blockExpression != null;
+ blockExpression.addRangeAfter(elements[0], elements[elements.length - 1], blockExpression.getFirstChild().getNextSibling());
+ ifExpression = (JavaFxExpression)parent.addBefore(ifExpression, elements[0]);
+ parent.deleteChildRange(elements[0], elements[elements.length - 1]);
+ ifExpression = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(ifExpression);
+ if (ifExpression != null) {
+ return ((JavaFxIfExpression)ifExpression).getCondition().getTextRange();
+ }
+ }
+ return null;
+ }
+}
--- /dev/null
+package org.jetbrains.javafx.refactoring.surround.surrounders.statements;
+
+import com.intellij.lang.surroundWith.Surrounder;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Created by IntelliJ IDEA.
+ * @author Alexey.Ivanov
+ */
+public abstract class JavaFxWithStatementSurrounder implements Surrounder {
+ @Override
+ public boolean isApplicable(@NotNull final PsiElement[] elements) {
+ return true;
+ }
+}
--- /dev/null
+package org.jetbrains.javafx.refactoring.surround.surrounders.statements;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.CodeInsightUtilBase;
+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.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.lang.psi.JavaFxBlockExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxWhileExpression;
+import org.jetbrains.javafx.refactoring.JavaFxChangeUtil;
+
+/**
+ * Created by IntelliJ IDEA.
+ * @author Alexey.Ivanov
+ */
+public class JavaFxWithWhileSurrounder extends JavaFxWithStatementSurrounder {
+ @Override
+ public String getTemplateDescription() {
+ return CodeInsightBundle.message("surround.with.while.template");
+ }
+
+ @Override
+ public TextRange surroundElements(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiElement[] elements)
+ throws IncorrectOperationException {
+ JavaFxExpression whileExpression = JavaFxChangeUtil.createExpressionFromText(project, "while (true) {\n\n}");
+ final PsiElement parent = elements[0].getParent();
+ if (whileExpression instanceof JavaFxWhileExpression) {
+ final JavaFxBlockExpression blockExpression = (JavaFxBlockExpression)((JavaFxWhileExpression)whileExpression).getBody();
+ assert blockExpression != null;
+ blockExpression.addRangeAfter(elements[0], elements[elements.length - 1], blockExpression.getFirstChild().getNextSibling());
+ whileExpression = (JavaFxExpression)parent.addBefore(whileExpression, elements[0]);
+ parent.deleteChildRange(elements[0], elements[elements.length - 1]);
+ whileExpression = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(whileExpression);
+ if (whileExpression != null) {
+ return ((JavaFxWhileExpression)whileExpression).getCondition().getTextRange();
+ }
+ }
+ return null;
+ }
+}
--- /dev/null
+var a = 3;<selection>
+var b = a * 3;
+var c = bind b;</selection>
\ No newline at end of file
--- /dev/null
+function foo(a: Integer) {
+ <selection> var b = a * 3;
+ </selection>return b + 5
+}
\ No newline at end of file
--- /dev/null
+function foo(a: Integer) {
+ if (<selection>true</selection>) {
+ var b = a * 3;
+ }
+ else {
+ }
+ return b + 5
+}
\ No newline at end of file
--- /dev/null
+var a = 3;
+if (<selection>true</selection>) {
+ var b = a * 3;
+ var c = bind b;
+}
\ No newline at end of file
--- /dev/null
+function foo(a: Integer) {
+ var b = 0;
+ <selection>b += a;
+ --a;
+ </selection>
+ return b;
+}
\ No newline at end of file
--- /dev/null
+function foo(a: Integer) {
+ var b = 0;
+ while (<selection>true</selection>) {
+ b += a;
+ --a;
+ }
+
+ return b;
+}
\ No newline at end of file
import org.jetbrains.javafx.refactoring.surround.surrounders.expressions.JavaFxWithNotInstanceofSurrounder;
import org.jetbrains.javafx.refactoring.surround.surrounders.expressions.JavaFxWithNotSurrounder;
import org.jetbrains.javafx.refactoring.surround.surrounders.expressions.JavaFxWithParenthesesSurrounder;
+import org.jetbrains.javafx.refactoring.surround.surrounders.statements.JavaFxWithIfElseSurrounder;
+import org.jetbrains.javafx.refactoring.surround.surrounders.statements.JavaFxWithIfSurrounder;
+import org.jetbrains.javafx.refactoring.surround.surrounders.statements.JavaFxWithWhileSurrounder;
import org.jetbrains.javafx.testUtils.JavaFxLightFixtureTestCase;
/**
* Created by IntelliJ IDEA.
- * @author: Alexey.Ivanov
+ * @author Alexey.Ivanov
*/
public class JavaFxSurroundWithTest extends JavaFxLightFixtureTestCase {
public void testParentheses() {
doTest(new JavaFxWithNotInstanceofSurrounder());
}
+ public void testIf() {
+ doTest(new JavaFxWithIfSurrounder());
+ }
+
+ public void testIfElse() {
+ doTest(new JavaFxWithIfElseSurrounder());
+ }
+
+ public void testWhile() {
+ doTest(new JavaFxWithWhileSurrounder());
+ }
+
private void doTest(final Surrounder surrounder) {
final String baseName = "/surround/" + getTestName(false);
myFixture.configureByFile(baseName + ".fx");