diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/KotlinCopyPasteReferenceProcessor.kt b/idea/src/org/jetbrains/jet/plugin/codeInsight/KotlinCopyPasteReferenceProcessor.kt index 131f50d2956..e88ac2f3638 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/KotlinCopyPasteReferenceProcessor.kt +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/KotlinCopyPasteReferenceProcessor.kt @@ -375,7 +375,7 @@ private fun PsiElement.isInCopiedArea(fileCopiedFrom: JetFile, startOffsets: Int } } -private val DeclarationDescriptor.importableFqName: FqName? +public val DeclarationDescriptor.importableFqName: FqName? get() { if (this is ConstructorDescriptor) return getContainingDeclaration().importableFqName val mayBeUnsafe = DescriptorUtils.getFqName(this) diff --git a/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java b/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java index afda892adb1..6ee81995a10 100644 --- a/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java +++ b/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java @@ -20,24 +20,25 @@ import com.google.common.collect.Lists; import com.intellij.lang.ImportOptimizer; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicatorProvider; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiReference; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.CallableDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.ImportPath; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; -import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.lang.resolve.name.NamePackage; +import org.jetbrains.jet.plugin.codeInsight.CodeInsightPackage; +import org.jetbrains.jet.plugin.references.JetReference; -import java.util.*; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import static org.jetbrains.jet.plugin.quickfix.ImportInsertHelper.needImport; @@ -128,196 +129,25 @@ public class JetImportOptimizer implements ImportOptimizer { } @Override - public void visitReferenceExpression(@NotNull JetReferenceExpression expression) { - if (PsiTreeUtil.getParentOfType(expression, JetImportDirective.class) == null && - PsiTreeUtil.getParentOfType(expression, JetPackageDirective.class) == null) { - - PsiReference reference = expression.getReference(); - if (reference != null) { - List references = new ArrayList(); - PsiElement resolve = reference.resolve(); - if (resolve != null) { - references.add(resolve); - } - - if (references.isEmpty() && reference instanceof PsiPolyVariantReference) { - for (ResolveResult resolveResult : ((PsiPolyVariantReference)reference).multiResolve(true)) { - references.add(resolveResult.getElement()); - } - } - - for (PsiElement psiReference : references) { - FqName fqName = getElementUsageFQName(psiReference); - if (fqName != null) { - usedQualifiedNames.add(fqName); - } + public void visitJetElement(@NotNull JetElement element) { + if (PsiTreeUtil.getParentOfType(element, JetImportDirective.class) != null || + PsiTreeUtil.getParentOfType(element, JetPackageDirective.class) != null) { + return; + } + PsiReference reference = element.getReference(); + if (reference instanceof JetReference) { + Collection referencedDescriptors = ((JetReference) reference).resolveToDescriptors(); + for (DeclarationDescriptor descriptor : referencedDescriptors) { + FqName importableFqName = CodeInsightPackage.getImportableFqName(descriptor); + if (importableFqName != null) { + usedQualifiedNames.add(importableFqName); } } } - - super.visitReferenceExpression(expression); - } - - @Override - public void visitForExpression(@NotNull JetForExpression expression) { - BindingContext context = AnalyzerFacadeWithCache.getContextForElement(expression); - ResolvedCall resolvedCall = context.get(BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL, expression.getLoopRange()); - addResolvedCallFqName(resolvedCall); - - super.visitForExpression(expression); - } - - @Override - public void visitMultiDeclaration(@NotNull JetMultiDeclaration declaration) { - BindingContext context = AnalyzerFacadeWithCache.getContextForElement(declaration); - List entries = declaration.getEntries(); - for (JetMultiDeclarationEntry entry : entries) { - ResolvedCall resolvedCall = context.get(BindingContext.COMPONENT_RESOLVED_CALL, entry); - addResolvedCallFqName(resolvedCall); - } - - super.visitMultiDeclaration(declaration); - } - - private void addResolvedCallFqName(@Nullable ResolvedCall resolvedCall) { - if (resolvedCall != null) { - CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); - usedQualifiedNames.add(DescriptorUtils.getFqNameSafe(resultingDescriptor)); - } + super.visitJetElement(element); } }); return usedQualifiedNames; } - - - @Nullable - public static FqName getElementUsageFQName(PsiElement element) { - if (element instanceof JetFile) { - return JetPsiUtil.getFQName((JetFile) element); - } - - if (element instanceof JetSimpleNameExpression) { - JetPackageDirective packageDirective = PsiTreeUtil.getParentOfType(element, JetPackageDirective.class); - if (packageDirective != null) { - List simpleNameExpressions = PsiTreeUtil.getChildrenOfTypeAsList(packageDirective, JetSimpleNameExpression.class); - FqName fqName = null; - for (JetSimpleNameExpression nameExpression : simpleNameExpressions) { - Name referencedName = nameExpression.getReferencedNameAsName(); - if (fqName == null) { - fqName = new FqName(referencedName.asString()); - } else { - fqName = fqName.child(referencedName); - } - if (nameExpression.equals(element)) { - return fqName; - } - } - } - } - - if (element instanceof JetNamedDeclaration) { - return JetPsiUtil.getFQName((JetNamedDeclaration) element); - } - - if (element instanceof PsiClass) { - String qualifiedName = ((PsiClass) element).getQualifiedName(); - if (qualifiedName != null) { - return new FqName(qualifiedName); - } - } - - if (element instanceof PsiField) { - PsiField field = (PsiField) element; - - FqName classFQN = getFqNameOfContainingClassForPsiMember(field); - if (classFQN == null) { - return null; - } - - return combineClassFqNameWithMemberName(field.getContainingClass(), classFQN, field.getName()); - } - - // TODO: Still problem with kotlin global properties imported from class files - if (element instanceof PsiMethod) { - PsiMethod method = (PsiMethod) element; - - FqName classFQN = getFqNameOfContainingClassForPsiMember(method); - if (classFQN == null) { - return null; - } - if (method.isConstructor()) { - return classFQN; - } - - return combineClassFqNameWithMemberName(method.getContainingClass(), classFQN, method.getName()); - } - - if (element instanceof PsiPackage) { - return new FqName(((PsiPackage) element).getQualifiedName()); - } - - return null; - } - - @Nullable - private static FqName combineClassFqNameWithMemberName(PsiClass containingClass, FqName classFQN, String memberName) { - if (memberName == null) { - return null; - } - if (JavaResolverPsiUtils.isCompiledKotlinPackageClass(containingClass)) { - return classFQN.parent().child(Name.identifier(memberName)); - } - else { - return classFQN.child(Name.identifier(memberName)); - } - } - - @Nullable - private static FqName getFqNameOfContainingClassForPsiMember(PsiMember member) { - PsiClass containingClass = member.getContainingClass(); - if (containingClass != null) { - String classFQNStr = containingClass.getQualifiedName(); - if (classFQNStr != null) { - return new FqName(classFQNStr); - } - } - return null; - } - - private static PsiElement getWithPreviousWhitespaces(PsiElement element) { - PsiElement result = element; - - PsiElement siblingIterator = element.getPrevSibling(); - while (siblingIterator != null) { - if (siblingIterator.getNode().getElementType() != TokenType.WHITE_SPACE) { - break; - } - else { - result = siblingIterator; - } - - siblingIterator = siblingIterator.getPrevSibling(); - } - - return result; - } - - private static PsiElement getWithFollowedWhitespaces(PsiElement element) { - PsiElement result = element; - - PsiElement siblingIterator = element.getNextSibling(); - while (siblingIterator != null) { - if (siblingIterator.getNode().getElementType() != TokenType.WHITE_SPACE) { - break; - } - else { - result = siblingIterator; - } - - siblingIterator = siblingIterator.getNextSibling(); - } - - return result; - } }