KT-2300 Auto-insertion of parenthesis by completion is not good for functions like "filter"

#KT-2300 fixed
This commit is contained in:
Evgeny Gerashchenko
2012-07-21 23:31:26 +04:00
parent 7c95c0a617
commit 03f38ef52a
8 changed files with 70 additions and 12 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.plugin.JetDescriptorIconProvider;
import org.jetbrains.jet.plugin.completion.handlers.JetClassInsertHandler;
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
@@ -41,10 +42,13 @@ import java.util.List;
public final class DescriptorLookupConverter {
private final static JetFunctionInsertHandler EMPTY_FUNCTION_HANDLER = new JetFunctionInsertHandler(
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS);
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS, JetFunctionInsertHandler.BracketType.PARENTHESIS);
private final static JetFunctionInsertHandler PARAMS_FUNCTION_HANDLER = new JetFunctionInsertHandler(
JetFunctionInsertHandler.CaretPosition.IN_BRACKETS);
private final static JetFunctionInsertHandler PARAMS_PARENTHESIS_FUNCTION_HANDLER = new JetFunctionInsertHandler(
JetFunctionInsertHandler.CaretPosition.IN_BRACKETS, JetFunctionInsertHandler.BracketType.PARENTHESIS);
private final static JetFunctionInsertHandler PARAMS_BRACES_FUNCTION_HANDLER = new JetFunctionInsertHandler(
JetFunctionInsertHandler.CaretPosition.IN_BRACKETS, JetFunctionInsertHandler.BracketType.BRACES);
private DescriptorLookupConverter() {}
@@ -79,7 +83,12 @@ public final class DescriptorLookupConverter {
element = element.setInsertHandler(EMPTY_FUNCTION_HANDLER);
}
else {
element = element.setInsertHandler(PARAMS_FUNCTION_HANDLER);
if (functionDescriptor.getValueParameters().size() == 1
&& JetStandardClasses.isFunctionType(functionDescriptor.getValueParameters().get(0).getType())) {
element = element.setInsertHandler(PARAMS_BRACES_FUNCTION_HANDLER);
} else {
element = element.setInsertHandler(PARAMS_PARENTHESIS_FUNCTION_HANDLER);
}
}
}
else if (descriptor instanceof VariableDescriptor) {
@@ -56,7 +56,7 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private final static InsertHandler<LookupElement> KEYWORDS_INSERT_HANDLER = new JetKeywordInsertHandler();
private final static InsertHandler<LookupElement> FUNCTION_INSERT_HANDLER = new JetFunctionInsertHandler(
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS);
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS, JetFunctionInsertHandler.BracketType.PARENTHESIS);
private final static ElementFilter GENERAL_FILTER = new NotFilter(new OrFilter(
new CommentFilter(), // or
@@ -47,11 +47,14 @@ import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper;
public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
public enum CaretPosition { IN_BRACKETS, AFTER_BRACKETS }
public enum BracketType { PARENTHESIS, BRACES }
private final CaretPosition caretPosition;
private final BracketType bracketType;
public JetFunctionInsertHandler(CaretPosition caretPosition) {
public JetFunctionInsertHandler(CaretPosition caretPosition, BracketType bracketType) {
this.caretPosition = caretPosition;
this.bracketType = bracketType;
}
@Override
@@ -87,22 +90,36 @@ public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
boolean bothParentheses = false;
String documentText = document.getText();
if (!(endOffset < documentText.length() && documentText.charAt(endOffset) == '(')) {
// Insert () if it's not already exist
document.insertString(endOffset, "()");
boolean braces = bracketType == BracketType.BRACES && context.getCompletionChar() != '(';
char openingBracket = braces ? '{' : '(';
char closingBracket = braces ? '}' : ')';
int openingBracketIndex = documentText.indexOf(openingBracket, endOffset);
if (openingBracketIndex != -1 && documentText.substring(endOffset, openingBracketIndex).trim().length() != 0) {
openingBracketIndex = -1; // opening bracket is too far
}
if (openingBracketIndex == -1) {
// Insert ()/{} if it's not already exist
if (braces) {
document.insertString(endOffset, " {}");
openingBracketIndex = endOffset + 1;
}
else {
document.insertString(endOffset, "()");
openingBracketIndex = endOffset;
}
bothParentheses = true;
}
else if (endOffset + 1 < documentText.length() && documentText.charAt(endOffset + 1) == ')') {
else if (openingBracketIndex + 1 < documentText.length() && documentText.charAt(openingBracketIndex + 1) == closingBracket) {
bothParentheses = true;
}
Editor editor = context.getEditor();
if (caretPosition == CaretPosition.IN_BRACKETS || !bothParentheses) {
editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 1);
editor.getCaretModel().moveToOffset(openingBracketIndex + 1);
AutoPopupController.getInstance(context.getProject()).autoPopupParameterInfo(editor, offsetElement);
}
else {
editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 2);
editor.getCaretModel().moveToOffset(openingBracketIndex + 2);
}
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
@@ -0,0 +1,5 @@
fun <T> jet.Array<T>.filter(predicate : (T) -> jet.Boolean) : java.util.List<T> = throw UnsupportedOperationException()
fun main(args: Array<String>) {
args.fil<caret>
}
@@ -0,0 +1,5 @@
fun <T> jet.Array<T>.filter(predicate : (T) -> jet.Boolean) : java.util.List<T> = throw UnsupportedOperationException()
fun main(args: Array<String>) {
args.filter {<caret>}
}
@@ -0,0 +1,7 @@
fun <T> jet.Array<T>.filter(predicate : (T) -> jet.Boolean) : java.util.List<T> = throw UnsupportedOperationException()
fun <T> jet.Array<T>.filterNot(predicate : (T) -> jet.Boolean) : java.util.List<T> = throw UnsupportedOperationException()
fun main(args: Array<String>) {
args.filter<caret> {it != ""}
}
@@ -0,0 +1,7 @@
fun <T> jet.Array<T>.filter(predicate : (T) -> jet.Boolean) : java.util.List<T> = throw UnsupportedOperationException()
fun <T> jet.Array<T>.filterNot(predicate : (T) -> jet.Boolean) : java.util.List<T> = throw UnsupportedOperationException()
fun main(args: Array<String>) {
args.filterNot {<caret>it != ""}
}
@@ -72,6 +72,14 @@ public class CompletionHandlerTest extends LightCompletionTestCase {
doTest();
}
public void testHigherOrderFunction() {
doTest();
}
public void testHigherOrderFunctionWithArg() {
doTest(CompletionType.BASIC, 2, "filterNot", null);
}
public void doTest() {
doTest(CompletionType.BASIC, 2, null, null);
}