Enable completion for top level functions from kotlin in kotlin mode
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user