diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 4492e250cfc..9f4256bebb5 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.plugin.caches; import com.google.common.base.Function; -import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; @@ -36,7 +35,10 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.asJava.JavaElementFinder; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.resolve.ImportPath; +import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; @@ -48,7 +50,6 @@ import org.jetbrains.jet.plugin.stubindex.JetExtensionFunctionNameIndex; import org.jetbrains.jet.plugin.stubindex.JetFullClassNameIndex; import org.jetbrains.jet.plugin.stubindex.JetShortClassNameIndex; import org.jetbrains.jet.plugin.stubindex.JetShortFunctionNameIndex; -import org.jetbrains.jet.util.QualifiedNamesUtil; import java.util.*; @@ -93,7 +94,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { List result = new ArrayList(); for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) { - if (QualifiedNamesUtil.fqnToShortName(new FqName(fqName)).getName().equals(name)) { + if ((new FqName(fqName)).shortName().getName().equals(name)) { PsiClass psiClass = javaElementFinder.findClass(fqName, scope); if (psiClass != null) { result.add(psiClass); @@ -129,17 +130,6 @@ public class JetShortNamesCache extends PsiShortNamesCache { return standardTypes; } - @NotNull - public Collection getFQNamesByName(@NotNull final String name, JetFile file, @NotNull GlobalSearchScope scope) { - BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext(); - return Collections2.filter(context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR), new Predicate() { - @Override - public boolean apply(@Nullable FqName fqName) { - return fqName != null && QualifiedNamesUtil.isShortNameForFQN(name, fqName); - } - }); - } - /** * Get jet non-extension top-level function names. Method is allowed to give invalid names - all result should be * checked with getTopLevelFunctionDescriptorsByName(). diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java index 25a9e4c8b53..fb49e881f31 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java @@ -30,28 +30,32 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; -import com.intellij.psi.search.DelegatingGlobalSearchScope; +import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiModifier; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.asJava.JetLightClass; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.Visibilities; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.ImportPath; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.JetBundle; -import org.jetbrains.jet.plugin.JetFileType; 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.WholeProjectAnalyzerFacade; import java.util.Collection; import java.util.Collections; @@ -100,8 +104,10 @@ public class ImportClassAndFunFix extends JetHintAction } }); } - - private static Collection getJetTopLevelFunctions(@NotNull String referenceName, JetSimpleNameExpression expression, @NotNull Project project) { + + private static Collection getJetTopLevelFunctions(@NotNull String referenceName, + JetSimpleNameExpression expression, + @NotNull Project project) { JetShortNamesCache namesCache = JetCacheManager.getInstance(project).getNamesCache(); Collection topLevelFunctions = namesCache.getTopLevelFunctionDescriptorsByName( referenceName, @@ -148,33 +154,58 @@ public class ImportClassAndFunFix extends JetHintAction public static Collection getClassNames(@NotNull String referenceName, @NotNull JetFile file) { final GlobalSearchScope scope = GlobalSearchScope.allScope(file.getProject()); Set possibleResolveNames = Sets.newHashSet(); - possibleResolveNames.addAll(JetCacheManager.getInstance(file.getProject()).getNamesCache().getFQNamesByName(referenceName, file, scope)); + possibleResolveNames.addAll(getJavaClasses(referenceName, file.getProject(), scope)); // TODO: Do appropriate sorting return Lists.newArrayList(possibleResolveNames); } - private static Collection getJavaClasses(@NotNull final String typeName, @NotNull Project project, final GlobalSearchScope scope) { + private static Collection getJavaClasses(@NotNull final String typeName, + @NotNull Project project, + final GlobalSearchScope scope) { PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project); - PsiClass[] classes = cache.getClassesByName(typeName, new DelegatingGlobalSearchScope(scope) { + PsiClass[] classes = cache.getClassesByName(typeName, scope); + + Collection accessibleClasses = Collections2.filter(Lists.newArrayList(classes), new Predicate() { @Override - public boolean contains(@NotNull VirtualFile file) { - return myBaseScope.contains(file) && file.getFileType() != JetFileType.INSTANCE; + public boolean apply(PsiClass psiClass) { + assert psiClass != null; + return isAccessible(psiClass); } }); - return Collections2.transform(Lists.newArrayList(classes), new Function() { + return Collections2.transform(accessibleClasses, new Function() { @Nullable @Override public FqName apply(@Nullable PsiClass javaClass) { assert javaClass != null; - return new FqName(javaClass.getQualifiedName()); + String qualifiedName = javaClass.getQualifiedName(); + assert qualifiedName != null; + return new FqName(qualifiedName); } }); } + private static boolean isAccessible(PsiMember member) { + if (member instanceof JetLightClass) { + // TODO: Now light class can't losing accessibility information + JetLightClass lightClass = (JetLightClass) member; + BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) lightClass.getContainingFile()).getBindingContext(); + ClassDescriptor descriptor = context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, lightClass.getFqName()); + + if (descriptor != null) { + return descriptor.getVisibility() == Visibilities.PUBLIC || descriptor.getVisibility() == Visibilities.INTERNAL; + } + else { + assert false : "Descriptor of the class isn't found in the binding context"; + } + } + + return member.hasModifierProperty(PsiModifier.PUBLIC) || member.hasModifierProperty(PsiModifier.PROTECTED); + } + @Override public boolean showHint(@NotNull Editor editor) { if (suggestions.isEmpty()) { @@ -220,7 +251,8 @@ public class ImportClassAndFunFix extends JetHintAction } @Override - public void invoke(@NotNull final Project project, @NotNull final Editor editor, final PsiFile file) throws IncorrectOperationException { + public void invoke(@NotNull final Project project, @NotNull final Editor editor, final PsiFile file) + throws IncorrectOperationException { CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { @Override public void run() { diff --git a/idea/testData/quickfix/autoImports/noImportForPrivateClass.after.kt b/idea/testData/quickfix/autoImports/noImportForPrivateClass.after.kt new file mode 100644 index 00000000000..880e647c559 --- /dev/null +++ b/idea/testData/quickfix/autoImports/noImportForPrivateClass.after.kt @@ -0,0 +1,5 @@ +// "Import Class" "false" + +fun test() { + PrivateClass +} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/noImportForPrivateClass.before.Main.kt b/idea/testData/quickfix/autoImports/noImportForPrivateClass.before.Main.kt new file mode 100644 index 00000000000..926bed4da6b --- /dev/null +++ b/idea/testData/quickfix/autoImports/noImportForPrivateClass.before.Main.kt @@ -0,0 +1,5 @@ +// "Import" "false" + +fun test() { + PrivateClass +} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/noImportForPrivateClass.before.data.Sample.kt b/idea/testData/quickfix/autoImports/noImportForPrivateClass.before.data.Sample.kt new file mode 100644 index 00000000000..cbd83c6a1c2 --- /dev/null +++ b/idea/testData/quickfix/autoImports/noImportForPrivateClass.before.data.Sample.kt @@ -0,0 +1,3 @@ +package sometest + +private class PrivateClass \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/AutoImportFixTest.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/AutoImportFixTest.java index a3c9ca3f741..920f5a9e83d 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/AutoImportFixTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/AutoImportFixTest.java @@ -38,6 +38,10 @@ public class AutoImportFixTest extends JetQuickFixMultiFileTest { doTest(); } + public void testNoImportForPrivateClass() throws Exception { + doTest(); + } + @Override protected String getCheckFileName() { return getTestName(true) + ".after.kt";