Enable completion for top level functions from kotlin in kotlin mode

This commit is contained in:
Nikolay Krasko
2012-02-03 17:02:04 +04:00
parent bd1bb1f0bd
commit cc19a21ff3
3 changed files with 46 additions and 44 deletions
@@ -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<String> getAllTopLevelFunctionNames() {
final HashSet<String> functionNames = new HashSet<String>();
@@ -145,9 +151,27 @@ public class JetShortNamesCache extends PsiShortNamesCache {
functionNames.addAll(JetFromJavaDescriptorHelper.getPossiblePackageDeclarationsNames(project, GlobalSearchScope.allScope(project)));
return functionNames;
}
public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName(final @NotNull String name, @NotNull GlobalSearchScope scope) {
return new ArrayList<FunctionDescriptor>();
@NotNull
public Collection<NamedFunctionDescriptor> 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<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope);
final BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCache(project, scope);
final HashSet<NamedFunctionDescriptor> result = new HashSet<NamedFunctionDescriptor>();
for (JetNamedFunction jetNamedFunction : jetNamedFunctions) {
final NamedFunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, jetNamedFunction);
if (functionDescriptor != null) {
result.add(functionDescriptor);
}
}
return result;
}
public Collection<JetNamedFunction> getTopLevelFunctionsByName(final @NotNull String name, @NotNull GlobalSearchScope scope) {
@@ -156,6 +180,9 @@ public class JetShortNamesCache extends PsiShortNamesCache {
@NotNull
public Collection<String> getAllJetExtensionFunctionsNames(@NotNull GlobalSearchScope scope) {
JetExtensionFunctionNameIndex.getInstance().getKey();
return JetFromJavaDescriptorHelper.getTopExtensionFunctionNames(null, project, scope);
}
@@ -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<CompletionParameters>() {
@@ -82,45 +79,24 @@ public class JetCompletionContributor extends CompletionContributor {
private static void addJetTopLevelFunctions(@NotNull CompletionResultSet result, @NotNull PsiElement position,
@NotNull final HashSet<LookupPositionObject> 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<String> 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<String> 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<LookupPositionObject> positions) {
CompletionResultSet tempResult = result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters));
@@ -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