From cc19a21ff300f16c7770f35837e7227cd2e5d943 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 3 Feb 2012 17:02:04 +0400 Subject: [PATCH] Enable completion for top level functions from kotlin in kotlin mode --- .../jet/plugin/caches/JetShortNamesCache.java | 39 +++++++++++++--- .../completion/JetCompletionContributor.java | 46 +++++-------------- .../JetMultifileBasicCompletionTest.java | 5 +- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 9bb5f851142..3c0ef5132b5 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -13,7 +13,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.asJava.JavaElementFinder; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.NamedFunctionDescriptor; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade; @@ -53,7 +53,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { } /** - * Return fake java names form jet project sources which should be visible from java. + * Return class names form jet sources in given scope which should be visible as java classes. */ @NotNull @Override @@ -137,7 +137,13 @@ public class JetShortNamesCache extends PsiShortNamesCache { } }); } - + + /** + * Get jet non-extension top-level function names. Method is allowed to give invalid names - all result should be + * checked with getTopLevelFunctionDescriptorsByName(). + * + * @return + */ @NotNull public Collection getAllTopLevelFunctionNames() { final HashSet functionNames = new HashSet(); @@ -145,9 +151,27 @@ public class JetShortNamesCache extends PsiShortNamesCache { functionNames.addAll(JetFromJavaDescriptorHelper.getPossiblePackageDeclarationsNames(project, GlobalSearchScope.allScope(project))); return functionNames; } - - public Collection getTopLevelFunctionDescriptorsByName(final @NotNull String name, @NotNull GlobalSearchScope scope) { - return new ArrayList(); + + @NotNull + public Collection getTopLevelFunctionDescriptorsByName(final @NotNull String name, + final @NotNull GlobalSearchScope scope) { + + // TODO: Add jet function in jar-dependencies (those functions are missing in BindingContext and stubs) + + final Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope); + + final BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCache(project, scope); + + final HashSet result = new HashSet(); + + for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { + final NamedFunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, jetNamedFunction); + if (functionDescriptor != null) { + result.add(functionDescriptor); + } + } + + return result; } public Collection getTopLevelFunctionsByName(final @NotNull String name, @NotNull GlobalSearchScope scope) { @@ -156,6 +180,9 @@ public class JetShortNamesCache extends PsiShortNamesCache { @NotNull public Collection getAllJetExtensionFunctionsNames(@NotNull GlobalSearchScope scope) { + + + JetExtensionFunctionNameIndex.getInstance().getKey(); return JetFromJavaDescriptorHelper.getTopExtensionFunctionNames(null, project, scope); } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index 6ff94379295..163ac99ee6a 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -31,9 +31,6 @@ import java.util.HashSet; * @author Nikolay Krasko */ public class JetCompletionContributor extends CompletionContributor { - - - public JetCompletionContributor() { extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new CompletionProvider() { @@ -82,45 +79,24 @@ public class JetCompletionContributor extends CompletionContributor { 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(); + + String actualPrefix = result.getPrefixMatcher().getPrefix(); - final JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final Collection functionNames = namesCache.getAllTopLevelFunctionNames(); + final Project project = position.getProject(); - for (String name : functionNames) { - if (name.contains(actualPrefix)) { - for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, scope)) { - addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(null, function, null), positions); - } + final JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache(); + final GlobalSearchScope scope = GlobalSearchScope.allScope(project); + final Collection functionNames = namesCache.getAllTopLevelFunctionNames(); + + for (String name : functionNames) { + if (name.contains(actualPrefix)) { + for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, scope)) { + addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(null, function, null), positions); } } } } - @Nullable - private static String getActualCompletionPrefix(@NotNull PsiElement position) { - if (position.getParent() instanceof JetSimpleNameExpression) { - final JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) position.getParent(); - - // Should be checked before call completion as pre-condition - assert (PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class) == null); - - final String referencedName = nameExpression.getReferencedName(); - - if (referencedName != null && referencedName.endsWith(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED)) { - int lastPrefixIndex = referencedName.length() - - CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED.length(); - - return referencedName.substring(0, lastPrefixIndex); - } - } - - return null; - } - private static void addClasses(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result, final HashSet positions) { CompletionResultSet tempResult = result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)); diff --git a/idea/tests/org/jetbrains/jet/completion/JetMultifileBasicCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/JetMultifileBasicCompletionTest.java index 24575ec0968..2665c0f7e0a 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetMultifileBasicCompletionTest.java +++ b/idea/tests/org/jetbrains/jet/completion/JetMultifileBasicCompletionTest.java @@ -7,8 +7,7 @@ import org.jetbrains.jet.plugin.PluginTestCaseBase; */ public class JetMultifileBasicCompletionTest extends JetCompletionMultiTestBase { - // TODO: fix and uncomment - public void skiptestTopLevelFunction() throws Exception { + public void testTopLevelFunction() throws Exception { doFileTest(); } @@ -19,7 +18,7 @@ public class JetMultifileBasicCompletionTest extends JetCompletionMultiTestBase @Override protected String getTestDataPath() { - return PluginTestCaseBase.getTestDataPathBase() + "/completion/basic/multifile"; + return PluginTestCaseBase.getTestDataPathBase() + "/completion/basic/multifile/"; } @Override