From bd068b750c9bbc2b5531672d6d04a5a6c3e74804 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 8 Jun 2012 12:27:15 +0400 Subject: [PATCH] Class import fix and completion for JS from lib --- .../jet/plugin/caches/JetShortNamesCache.java | 22 +++++++++++++++- .../JetClassCompletionContributor.java | 25 +++++++++--------- .../plugin/quickfix/ImportClassAndFunFix.java | 26 +++++++++++++++++-- .../stubindex/JetFullClassNameIndex.java | 4 +-- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 9f4256bebb5..14793efa617 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -80,7 +80,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { } /** - * Return class names form jet sources in given scope which should be visible as java classes. + * Return class names form jet sources in given scope which should be visible as Java classes. */ @NotNull @Override @@ -265,6 +265,26 @@ public class JetShortNamesCache extends PsiShortNamesCache { return resultDescriptors; } + public Collection getJetClassesDescriptors( + @NotNull Condition acceptedShortNameCondition, + @NotNull JetFile jetFile + ) { + BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(jetFile).getBindingContext(); + Collection classDescriptors = new ArrayList(); + + for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) { + FqName classFQName = new FqName(fqName); + if (acceptedShortNameCondition.value(classFQName.shortName().getName())) { + ClassDescriptor descriptor = context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, classFQName); + if (descriptor != null) { + classDescriptors.add(descriptor); + } + } + } + + return classDescriptors; + } + @NotNull @Override public PsiMethod[] getMethodsByName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope) { diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java index 4cc8d39e4f8..be12bdb1f3c 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java @@ -18,12 +18,12 @@ package org.jetbrains.jet.plugin.completion; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.util.Consumer; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; @@ -118,18 +118,19 @@ public class JetClassCompletionContributor extends CompletionContributor { }); } else { - GlobalSearchScope globalSearchScope = GlobalSearchScope.allScope(parameters.getOriginalFile().getProject()); - PsiShortNamesCache cache = JetCacheManager.getInstance(parameters.getOriginalFile().getProject()).getShortNamesCache( + Project project = parameters.getOriginalFile().getProject(); + JetShortNamesCache namesCache = JetCacheManager.getInstance(project).getNamesCache(); + Collection descriptors = namesCache.getJetClassesDescriptors( + new Condition() { + @Override + public boolean value(String shortName) { + return result.getPrefixMatcher().prefixMatches(shortName); + } + }, (JetFile) parameters.getOriginalFile()); - for (String className : cache.getAllClassNames()) { - if (result.getPrefixMatcher().prefixMatches(className)) { - for (PsiClass aClass : cache.getClassesByName(className, globalSearchScope)) { - if (!addAsJetLookupElement(aClass, bindingContext, consumer)) { - assert false : "All classes should be possible to add as kotlin classes in JS project"; - } - } - } + for (ClassDescriptor descriptor : descriptors) { + consumer.consume(DescriptorLookupConverter.createLookupElement(bindingContext, descriptor)); } } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java index 2bf9543f068..a705df0789a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java @@ -55,6 +55,7 @@ import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.actions.JetAddImportAction; import org.jetbrains.jet.plugin.caches.JetCacheManager; import org.jetbrains.jet.plugin.caches.JetShortNamesCache; +import org.jetbrains.jet.plugin.project.JsModuleDetector; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import java.util.Collection; @@ -152,10 +153,14 @@ public class ImportClassAndFunFix extends JetHintAction * Searches for possible class names in kotlin context and java facade. */ public static Collection getClassNames(@NotNull String referenceName, @NotNull JetFile file) { - final GlobalSearchScope scope = GlobalSearchScope.allScope(file.getProject()); Set possibleResolveNames = Sets.newHashSet(); - possibleResolveNames.addAll(getClassesFromCache(referenceName, file)); + if (!JsModuleDetector.isJsModule(file)) { + possibleResolveNames.addAll(getClassesFromCache(referenceName, file)); + } + else { + possibleResolveNames.addAll(getJetClasses(referenceName, file)); + } // TODO: Do appropriate sorting return Lists.newArrayList(possibleResolveNames); @@ -186,6 +191,23 @@ public class ImportClassAndFunFix extends JetHintAction }); } + private static Collection getJetClasses(@NotNull final String typeName, @NotNull JetFile file) { + JetShortNamesCache cache = JetCacheManager.getInstance(file.getProject()).getNamesCache(); + Collection descriptors = cache.getJetClassesDescriptors(new Condition() { + @Override + public boolean value(String s) { + return typeName.equals(s); + } + }, file); + + return Collections2.transform(descriptors, new Function() { + @Override + public FqName apply(ClassDescriptor descriptor) { + return DescriptorUtils.getFQName(descriptor).toSafe(); + } + }); + } + private static boolean isAccessible(PsiMember member) { if (member instanceof JetLightClass) { // TODO: Now light classes losing accessibility information diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/JetFullClassNameIndex.java b/idea/src/org/jetbrains/jet/plugin/stubindex/JetFullClassNameIndex.java index ac1f2a20539..b9da5a94d03 100644 --- a/idea/src/org/jetbrains/jet/plugin/stubindex/JetFullClassNameIndex.java +++ b/idea/src/org/jetbrains/jet/plugin/stubindex/JetFullClassNameIndex.java @@ -42,7 +42,7 @@ public class JetFullClassNameIndex extends StringStubIndexExtension get(final String integer, final Project project, @NotNull final GlobalSearchScope scope) { - return super.get(integer, project, new JetSourceFilterScope(scope)); + public Collection get(final String fqName, final Project project, @NotNull final GlobalSearchScope scope) { + return super.get(fqName, project, new JetSourceFilterScope(scope)); } }