mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IDEA-69972 Smart Complete Statement: Leave code block if the action is called for the complete statement
This commit is contained in:
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.editorActions.smartEnter;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.PsiCodeBlock;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReturnStatement;
|
||||
import com.intellij.psi.PsiThrowStatement;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: max
|
||||
* Date: Sep 8, 2003
|
||||
* Time: 2:48:47 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class BreakingControlFlowEnterProcessor implements EnterProcessor {
|
||||
public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) {
|
||||
if (psiElement instanceof PsiReturnStatement || psiElement instanceof PsiThrowStatement) {
|
||||
PsiElement parent = psiElement.getParent();
|
||||
if (!(parent instanceof PsiCodeBlock)) return false;
|
||||
editor.getCaretModel().moveToOffset(parent.getTextRange().getEndOffset());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -80,7 +80,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
List<EnterProcessor> processors = new ArrayList<EnterProcessor>();
|
||||
processors.add(new CommentBreakerEnterProcessor());
|
||||
processors.add(new AfterSemicolonEnterProcessor());
|
||||
processors.add(new BreakingControlFlowEnterProcessor());
|
||||
processors.add(new LeaveCodeBlockEnterProcessor());
|
||||
processors.add(new PlainEnterProcessor());
|
||||
ourEnterProcessors = processors.toArray(new EnterProcessor[processors.size()]);
|
||||
}
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.editorActions.smartEnter;
|
||||
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
|
||||
import com.intellij.psi.PsiCodeBlock;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReturnStatement;
|
||||
import com.intellij.psi.PsiThrowStatement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: max
|
||||
* Date: Sep 8, 2003
|
||||
* Time: 2:48:47 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class LeaveCodeBlockEnterProcessor implements EnterProcessor {
|
||||
|
||||
private static final TokenSet CONTROL_FLOW_ELEMENT_TYPES = TokenSet.create(
|
||||
JavaElementType.IF_STATEMENT, JavaElementType.WHILE_STATEMENT, JavaElementType.DO_WHILE_STATEMENT, JavaElementType.FOR_STATEMENT,
|
||||
JavaElementType.FOREACH_STATEMENT
|
||||
);
|
||||
|
||||
public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) {
|
||||
PsiElement parent = psiElement.getParent();
|
||||
if (!(parent instanceof PsiCodeBlock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean leaveCodeBlock = isControlFlowBreak(psiElement) || isValidStatementInsideControlFlowOperator(psiElement, isModified);
|
||||
if (!leaveCodeBlock) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int offset = parent.getTextRange().getEndOffset();
|
||||
|
||||
// Check if there is empty line after the code block. Just move caret there in the case of the positive answer.
|
||||
final CharSequence text = editor.getDocument().getCharsSequence();
|
||||
if (offset < text.length() - 1) {
|
||||
final int i = CharArrayUtil.shiftForward(text, offset + 1, " \t");
|
||||
if (i < text.length() && text.charAt(i) == '\n') {
|
||||
editor.getCaretModel().moveToOffset(offset + 1);
|
||||
EditorActionManager actionManager = EditorActionManager.getInstance();
|
||||
EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_LINE_END);
|
||||
final DataContext dataContext = DataManager.getInstance().getDataContext(editor.getComponent());
|
||||
if (dataContext != null) {
|
||||
actionHandler.execute(editor, dataContext);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles situations like the one below:
|
||||
* <pre>
|
||||
* void foo(int i) {
|
||||
* if (i < 0) {
|
||||
* return;[caret]
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <b>Output:</b>
|
||||
* <pre>
|
||||
* void foo(int i) {
|
||||
* if (i < 0) {
|
||||
* return;
|
||||
* }
|
||||
* [caret]
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
private static boolean isControlFlowBreak(@Nullable PsiElement element) {
|
||||
return element instanceof PsiReturnStatement || element instanceof PsiThrowStatement;
|
||||
}
|
||||
|
||||
private static boolean isValidStatementInsideControlFlowOperator(@Nullable PsiElement element, boolean modified) {
|
||||
if (modified || element == null || PsiTreeUtil.hasErrorElements(element)) {
|
||||
return false;
|
||||
}
|
||||
final ASTNode node = element.getNode();
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !CONTROL_FLOW_ELEMENT_TYPES.contains(node.getElementType());
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,6 @@
|
||||
public class Foo {
|
||||
{
|
||||
foo(x);
|
||||
<caret>
|
||||
}
|
||||
<caret>
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
public class Foo {
|
||||
public void foo() {
|
||||
String s = "abcdef";
|
||||
<caret>
|
||||
}
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
public class Foo {
|
||||
void test(int i) {
|
||||
if (i > 1) {
|
||||
i <caret>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class Foo {
|
||||
void test(int i) {
|
||||
while (i-- > 1) {
|
||||
i <caret>= 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class Foo {
|
||||
void test(int i) {
|
||||
while (i-- > 1) {
|
||||
i = 1;
|
||||
}
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
public class Foo {
|
||||
void test(int i) {
|
||||
if (i > 1) {
|
||||
i = 1;
|
||||
}
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,6 @@
|
||||
public class Test {
|
||||
public void foo() {
|
||||
int x = 2;
|
||||
<caret>
|
||||
}
|
||||
<caret>
|
||||
}
|
||||
@@ -215,6 +215,10 @@ public class CompleteStatementTest extends EditorActionTestCase {
|
||||
}
|
||||
|
||||
public void testForUpdateGeneration() throws Exception { doTest(); }
|
||||
|
||||
public void testLeaveValidCodeBlock() throws Exception { doTest(); }
|
||||
|
||||
public void testLeaveValidCodeBlockWithEmptyLineAfterIt() throws Exception { doTest(); }
|
||||
|
||||
private void doTestBracesNextLineStyle() throws Exception {
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
|
||||
|
||||
Reference in New Issue
Block a user