mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-140452 Complete-statement insert closing parenthesis at wrong place
This commit is contained in:
+45
-7
@@ -16,10 +16,14 @@
|
||||
package com.intellij.codeInsight.editorActions.smartEnter;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspMethodCall;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -38,17 +42,20 @@ public class MethodCallFixer implements Fixer {
|
||||
args = ((PsiNewExpression) psiElement).getArgumentList();
|
||||
}
|
||||
|
||||
if (args == null) return;
|
||||
if (args != null && !hasRParenth(args)) {
|
||||
int caret = editor.getCaretModel().getOffset();
|
||||
PsiCallExpression innermostCall = PsiTreeUtil.findElementOfClassAtOffset(psiElement.getContainingFile(), caret, PsiCallExpression.class, false);
|
||||
if (innermostCall == null) return;
|
||||
|
||||
PsiElement parenth = args.getLastChild();
|
||||
args = innermostCall.getArgumentList();
|
||||
if (args == null) return;
|
||||
|
||||
if (parenth == null || !")".equals(parenth.getText())) {
|
||||
int endOffset = -1;
|
||||
PsiElement child = args.getFirstChild();
|
||||
while (child != null) {
|
||||
if (child instanceof PsiErrorElement) {
|
||||
final PsiErrorElement errorElement = (PsiErrorElement)child;
|
||||
if (errorElement.getErrorDescription().indexOf("')'") >= 0) {
|
||||
if (errorElement.getErrorDescription().contains("')'")) {
|
||||
endOffset = errorElement.getTextRange().getStartOffset();
|
||||
break;
|
||||
}
|
||||
@@ -62,17 +69,48 @@ public class MethodCallFixer implements Fixer {
|
||||
|
||||
final PsiExpression[] params = args.getExpressions();
|
||||
if (params.length > 0 &&
|
||||
startLine(editor, args) != startLine(editor, params[0]) &&
|
||||
editor.getCaretModel().getOffset() < params[0].getTextRange().getStartOffset()) {
|
||||
startLine(editor, args) != startLine(editor, params[0]) &&
|
||||
caret < params[0].getTextRange().getStartOffset()) {
|
||||
endOffset = args.getTextRange().getStartOffset() + 1;
|
||||
}
|
||||
|
||||
if (!DumbService.isDumb(args.getProject())) {
|
||||
Integer argCount = getUnambiguousParameterCount(innermostCall);
|
||||
if (argCount != null && argCount > 0 && argCount < params.length) {
|
||||
endOffset = Math.min(endOffset, params[argCount - 1].getTextRange().getEndOffset());
|
||||
}
|
||||
}
|
||||
|
||||
endOffset = CharArrayUtil.shiftBackward(editor.getDocument().getCharsSequence(), endOffset - 1, " \t\n") + 1;
|
||||
editor.getDocument().insertString(endOffset, ")");
|
||||
editor.getCaretModel().moveToOffset(endOffset + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private int startLine(Editor editor, PsiElement psiElement) {
|
||||
private static boolean hasRParenth(PsiExpressionList args) {
|
||||
PsiElement parenth = args.getLastChild();
|
||||
return parenth != null && ")".equals(parenth.getText());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Integer getUnambiguousParameterCount(PsiCallExpression call) {
|
||||
int argCount = -1;
|
||||
for (CandidateInfo candidate : PsiResolveHelper.SERVICE.getInstance(call.getProject()).getReferencedMethodCandidates(call, false)) {
|
||||
PsiElement element = candidate.getElement();
|
||||
if (!(element instanceof PsiMethod)) return null;
|
||||
if (((PsiMethod)element).isVarArgs()) return null;
|
||||
|
||||
int count = ((PsiMethod)element).getParameterList().getParametersCount();
|
||||
if (argCount == -1) {
|
||||
argCount = count;
|
||||
} else if (argCount != count) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return argCount;
|
||||
}
|
||||
|
||||
private static int startLine(Editor editor, PsiElement psiElement) {
|
||||
return editor.getDocument().getLineNumber(psiElement.getTextRange().getStartOffset());
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Main {
|
||||
public void test() {
|
||||
Path path = Paths.get("/tmp");
|
||||
foo(getf<caret>path, 5);
|
||||
}
|
||||
|
||||
private String getFileName(Path path) { return path.toString(); }
|
||||
private void foo(String text, int count) {}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Main {
|
||||
public void test() {
|
||||
Path path = Paths.get("/tmp");
|
||||
foo(getFileName(path), 5);<caret>
|
||||
}
|
||||
|
||||
private String getFileName(Path path) { return path.toString(); }
|
||||
private void foo(String text, int count) {}
|
||||
}
|
||||
+1
@@ -934,6 +934,7 @@ public class ListUtils {
|
||||
public void testSmartEnterWrapsConstructorCall() throws Throwable { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR as String) }
|
||||
public void testSmartEnterNoNewLine() { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR as String) }
|
||||
public void testSmartEnterWithNewLine() { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR as String) }
|
||||
public void testSmartEnterGuessArgumentCount() throws Throwable { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR as String) }
|
||||
|
||||
public void testTabReplacesMethodNameWithLocalVariableName() throws Throwable { doTest('\t'); }
|
||||
public void testMethodParameterAnnotationClass() throws Throwable { doTest(); }
|
||||
|
||||
Reference in New Issue
Block a user