KT-1808 Auto import offers private static Java classes
#KT-1808 fixed
This commit is contained in:
@@ -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<PsiClass> result = new ArrayList<PsiClass>();
|
||||
|
||||
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<FqName> 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<FqName>() {
|
||||
@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().
|
||||
|
||||
@@ -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<JetSimpleNameExpression>
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Collection<FqName> getJetTopLevelFunctions(@NotNull String referenceName, JetSimpleNameExpression expression, @NotNull Project project) {
|
||||
|
||||
private static Collection<FqName> getJetTopLevelFunctions(@NotNull String referenceName,
|
||||
JetSimpleNameExpression expression,
|
||||
@NotNull Project project) {
|
||||
JetShortNamesCache namesCache = JetCacheManager.getInstance(project).getNamesCache();
|
||||
Collection<FunctionDescriptor> topLevelFunctions = namesCache.getTopLevelFunctionDescriptorsByName(
|
||||
referenceName,
|
||||
@@ -148,33 +154,58 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
|
||||
public static Collection<FqName> getClassNames(@NotNull String referenceName, @NotNull JetFile file) {
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(file.getProject());
|
||||
Set<FqName> 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<FqName> getJavaClasses(@NotNull final String typeName, @NotNull Project project, final GlobalSearchScope scope) {
|
||||
private static Collection<FqName> 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<PsiClass> accessibleClasses = Collections2.filter(Lists.newArrayList(classes), new Predicate<PsiClass>() {
|
||||
@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<PsiClass, FqName>() {
|
||||
return Collections2.transform(accessibleClasses, new Function<PsiClass, FqName>() {
|
||||
@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<JetSimpleNameExpression>
|
||||
}
|
||||
|
||||
@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() {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Import Class" "false"
|
||||
|
||||
fun test() {
|
||||
PrivateClass
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Import" "false"
|
||||
|
||||
fun test() {
|
||||
<caret>PrivateClass
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package sometest
|
||||
|
||||
private class PrivateClass
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user