From 24785826707c98d8b20975c02db6da733c7f1058 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 2 Feb 2012 16:46:43 +0400 Subject: [PATCH] Simple handler with insertion imports for classes names completion --- .../completion/JetCompletionContributor.java | 133 +++++++----------- .../handlers/JetJavaClassInsertHandler.java | 28 ++++ .../handlers/InsertJavaClassImport.kt | 5 + .../handlers/InsertJavaClassImport.kt.after | 3 + 4 files changed, 86 insertions(+), 83 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/completion/handlers/JetJavaClassInsertHandler.java create mode 100644 idea/testData/completion/handlers/InsertJavaClassImport.kt create mode 100644 idea/testData/completion/handlers/InsertJavaClassImport.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index a99f58b4f3a..6ff94379295 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.psi.JetUserType; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.caches.JetCacheManager; import org.jetbrains.jet.plugin.caches.JetShortNamesCache; +import org.jetbrains.jet.plugin.completion.handlers.JetJavaClassInsertHandler; import org.jetbrains.jet.plugin.references.JetSimpleNameReference; import java.util.Collection; @@ -31,8 +32,7 @@ import java.util.HashSet; */ public class JetCompletionContributor extends CompletionContributor { - // A hack to avoid doubling of completion - final HashSet positions = new HashSet(); + public JetCompletionContributor() { extend(CompletionType.BASIC, PlatformPatterns.psiElement(), @@ -41,54 +41,47 @@ public class JetCompletionContributor extends CompletionContributor { protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, final @NotNull CompletionResultSet result) { - synchronized (positions) { - positions.clear(); + final HashSet positions = new HashSet(); - if (result.getPrefixMatcher().getPrefix().isEmpty()) { - return; - } - - final PsiElement position = parameters.getPosition(); - if (!(position.getContainingFile() instanceof JetFile)) { - return; - } - - final JetSimpleNameReference jetReference = getJetReference(parameters); - if (jetReference != null) { - for (Object variant : jetReference.getVariants()) { - addReferenceVariant(result, variant); - } - } - -// final JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache(); -// final GlobalSearchScope scope = GlobalSearchScope.allScope(parameters.getPosition().getProject()); -// final Collection functionNames = namesCache.getAllJetExtensionFunctionsNames(scope); - - if (shouldRunClassNameCompletion(parameters)) { - addJavaClasses(parameters, result); - // addJetClasses(result, position); - } - - if (shouldRunFunctionNameCompletion(parameters)) { - addJetTopLevelFunctions(result, position); - } - - result.stopHere(); + if (result.getPrefixMatcher().getPrefix().isEmpty()) { + return; } + + final PsiElement position = parameters.getPosition(); + if (!(position.getContainingFile() instanceof JetFile)) { + return; + } + + final JetSimpleNameReference jetReference = getJetReference(parameters); + if (jetReference != null) { + for (Object variant : jetReference.getVariants()) { + addReferenceVariant(result, variant, positions); + } + } + + if (shouldRunTopLevelCompletion(parameters)) { + // Jet classes will be added as java completions for unification + addClasses(parameters, result, positions); + addJetTopLevelFunctions(result, position, positions); + } + + result.stopHere(); } }); } - private void addReferenceVariant(@NotNull CompletionResultSet result, @NotNull Object variant) { + private static void addReferenceVariant(@NotNull CompletionResultSet result, @NotNull Object variant, + @NotNull final HashSet positions) { if (variant instanceof LookupElement) { - addCompletionToResult(result, (LookupElement) variant); + addCompletionToResult(result, (LookupElement) variant, positions); } else { - addCompletionToResult(result, LookupElementBuilder.create(variant.toString())); + addCompletionToResult(result, LookupElementBuilder.create(variant.toString()), positions); } } - private void addJetTopLevelFunctions(@NotNull CompletionResultSet result, @NotNull PsiElement position) { + private static void addJetTopLevelFunctions(@NotNull CompletionResultSet result, @NotNull PsiElement position, + @NotNull final HashSet positions) { String actualPrefix = getActualCompletionPrefix(position); if (actualPrefix != null) { final Project project = position.getProject(); @@ -100,42 +93,13 @@ public class JetCompletionContributor extends CompletionContributor { for (String name : functionNames) { if (name.contains(actualPrefix)) { for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, scope)) { - addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(null, function, null)); + addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(null, function, null), positions); } - -// for (JetNamedFunction function : namesCache.getTopLevelFunctionsByName(name, scope)) { -// String functionName = function.getName(); -// String qualifiedName = function.getQualifiedName(); -// assert functionName != null; -// -// final LookupElementBuilder lookup = LookupElementBuilder.create( -// new LookupPositionObject(function), functionName); -// -// if (qualifiedName != null) { -// lookup.setTailText(qualifiedName); -// } -// -// addCompletionToResult(result, lookup); -// } } } } } -// private void addJetClasses(@NotNull CompletionResultSet result, @NotNull PsiElement position) { -// String actualPrefix = getActualCompletionPrefix(position); -// if (actualPrefix != null) { -// final Collection classDescriptors = -// JetCacheManager.getInstance(position.getProject()).getNamesCache().getClassDescriptors(); -// -// for (ClassDescriptor descriptor : classDescriptors) { -// if (descriptor.getName().startsWith(actualPrefix)) { -// addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(null, descriptor, null)); -// } -// } -// } -// } - @Nullable private static String getActualCompletionPrefix(@NotNull PsiElement position) { if (position.getParent() instanceof JetSimpleNameExpression) { @@ -157,25 +121,28 @@ public class JetCompletionContributor extends CompletionContributor { return null; } - private void addJavaClasses(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result) { - + private static void addClasses(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result, final HashSet positions) { CompletionResultSet tempResult = result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)); - JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting( - parameters, tempResult), parameters.getInvocationCount() <= 1, new Consumer() { + JavaClassNameCompletionContributor.addAllClasses( + parameters, + JavaCompletionSorting.addJavaSorting(parameters, tempResult), + parameters.getInvocationCount() <= 2, + new Consumer() { + @Override + public void consume(@NotNull LookupElement element) { + // Redefine standard java insert handler which is going to insert fqn + if (element instanceof JavaPsiClassReferenceElement) { + JavaPsiClassReferenceElement javaPsiReferenceElement = (JavaPsiClassReferenceElement) element; + javaPsiReferenceElement.setInsertHandler(JetJavaClassInsertHandler.JAVA_CLASS_INSERT_HANDLER); + } - @Override - public void consume(@NotNull LookupElement element) { - addCompletionToResult(result, element); - } - }); + addCompletionToResult(result, element, positions); + } + }); } - private static boolean shouldRunFunctionNameCompletion(@NotNull CompletionParameters parameters) { - return shouldRunClassNameCompletion(parameters); - } - - private static boolean shouldRunClassNameCompletion(@NotNull CompletionParameters parameters) { + private static boolean shouldRunTopLevelCompletion(@NotNull CompletionParameters parameters) { final PsiElement element = parameters.getPosition(); if (parameters.getInvocationCount() > 1) { @@ -219,7 +186,7 @@ public class JetCompletionContributor extends CompletionContributor { return null; } - private void addCompletionToResult(@NotNull final CompletionResultSet result, LookupElement element) { + private static void addCompletionToResult(@NotNull final CompletionResultSet result, LookupElement element, HashSet positions) { if (element.getObject() instanceof LookupPositionObject) { final LookupPositionObject positionObject = (LookupPositionObject) element.getObject(); diff --git a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetJavaClassInsertHandler.java b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetJavaClassInsertHandler.java new file mode 100644 index 00000000000..989083d0693 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetJavaClassInsertHandler.java @@ -0,0 +1,28 @@ +package org.jetbrains.jet.plugin.completion.handlers; + +import com.intellij.codeInsight.completion.InsertHandler; +import com.intellij.codeInsight.completion.InsertionContext; +import com.intellij.codeInsight.completion.JavaPsiClassReferenceElement; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.plugin.quickfix.ImportClassHelper; + +/** + * Handler for inserting java class completion. + * - Should place import directive if necessary. + * + * @author Nikolay Krasko + */ +public class JetJavaClassInsertHandler implements InsertHandler { + public static final InsertHandler JAVA_CLASS_INSERT_HANDLER = new JetJavaClassInsertHandler(); + + public void handleInsert(final InsertionContext context, final JavaPsiClassReferenceElement item) { + if (context.getFile() instanceof JetFile) { + final JetFile jetFile = (JetFile) context.getFile(); + ImportClassHelper.addImportDirective(item.getQualifiedName(), jetFile); + } + + // check annotation + // check auto insert parentheses + // check auto insert type parameters + } +} diff --git a/idea/testData/completion/handlers/InsertJavaClassImport.kt b/idea/testData/completion/handlers/InsertJavaClassImport.kt new file mode 100644 index 00000000000..b6a6d864fc9 --- /dev/null +++ b/idea/testData/completion/handlers/InsertJavaClassImport.kt @@ -0,0 +1,5 @@ +fun other() { + HashSe +} + +// INSERT: HashSet \ No newline at end of file diff --git a/idea/testData/completion/handlers/InsertJavaClassImport.kt.after b/idea/testData/completion/handlers/InsertJavaClassImport.kt.after new file mode 100644 index 00000000000..8ba89818172 --- /dev/null +++ b/idea/testData/completion/handlers/InsertJavaClassImport.kt.after @@ -0,0 +1,3 @@ +fun other() { + HashSe +} \ No newline at end of file