Code refactorings

This commit is contained in:
Valentin Kipyatkov
2014-08-13 14:16:11 +04:00
parent ced2abb860
commit 2841fab6d5
3 changed files with 22 additions and 70 deletions
@@ -26,22 +26,7 @@ import com.intellij.util.Processor
import com.intellij.util.containers.ContainerUtil import com.intellij.util.containers.ContainerUtil
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
import org.jetbrains.jet.asJava.JavaElementFinder import org.jetbrains.jet.asJava.JavaElementFinder
import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.psi.*
import org.jetbrains.jet.lang.psi.psiUtil.*
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.lazy.KotlinCodeAnalyzer
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils
import org.jetbrains.jet.plugin.caches.resolve.IDELightClassGenerationSupport import org.jetbrains.jet.plugin.caches.resolve.IDELightClassGenerationSupport
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
import org.jetbrains.jet.plugin.stubindex.* import org.jetbrains.jet.plugin.stubindex.*
import java.util.* import java.util.*
@@ -53,15 +38,10 @@ import com.intellij.util.containers
*/ */
public class JetShortNamesCache(private val project: Project) : PsiShortNamesCache() { public class JetShortNamesCache(private val project: Project) : PsiShortNamesCache() {
class object { class object {
public fun getKotlinInstance(project: Project): JetShortNamesCache { public fun getKotlinInstance(project: Project): JetShortNamesCache
val extensions = Extensions.getArea(project).getExtensionPoint<PsiShortNamesCache>(PsiShortNamesCache.EP_NAME).getExtensions() = Extensions.getArea(project).getExtensionPoint<PsiShortNamesCache>(PsiShortNamesCache.EP_NAME).getExtensions()
for (extension in extensions) { .filterIsInstance(javaClass<JetShortNamesCache>())
if (extension is JetShortNamesCache) { .first()
return extension as JetShortNamesCache
}
}
throw IllegalStateException(javaClass<JetShortNamesCache>().getSimpleName() + " is not found for project " + project)
}
} }
/** /**
@@ -171,8 +171,4 @@ public class KotlinIndicesHelper(private val project: Project) {
val allDescriptors = QualifiedExpressionResolver().analyseImportReference(importDirective, jetScope, BindingTraceContext(), resolveSession.getModuleDescriptor()) val allDescriptors = QualifiedExpressionResolver().analyseImportReference(importDirective, jetScope, BindingTraceContext(), resolveSession.getModuleDescriptor())
return allDescriptors.filterIsInstance(javaClass<CallableDescriptor>()).filter { it.getReceiverParameter() == null } return allDescriptors.filterIsInstance(javaClass<CallableDescriptor>()).filter { it.getReceiverParameter() == null }
} }
public fun getClassDescriptorsByName(name: String, analyzer: KotlinCodeAnalyzer, scope: GlobalSearchScope): Collection<ClassDescriptor> {
return JetShortNamesCache.getKotlinInstance(project).getClassesByName(name, scope).flatMap { ResolveSessionUtils.getClassDescriptorsByFqName(analyzer, FqName(it.getQualifiedName()!!)) }
}
} }
@@ -16,7 +16,6 @@
package org.jetbrains.jet.plugin.quickfix package org.jetbrains.jet.plugin.quickfix
import com.google.common.collect.Lists
import com.intellij.codeInsight.daemon.impl.ShowAutoImportPass import com.intellij.codeInsight.daemon.impl.ShowAutoImportPass
import com.intellij.codeInsight.hint.HintManager import com.intellij.codeInsight.hint.HintManager
import com.intellij.codeInsight.intention.HighPriorityAction import com.intellij.codeInsight.intention.HighPriorityAction
@@ -47,7 +46,7 @@ import org.jetbrains.jet.plugin.project.ProjectStructureUtil
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
import org.jetbrains.jet.plugin.util.JetPsiHeuristicsUtil import org.jetbrains.jet.plugin.util.JetPsiHeuristicsUtil
import java.util.ArrayList import java.util.ArrayList
import com.intellij.codeInsight.intention.IntentionAction import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils
/** /**
* Check possibility and perform fix for unresolved references. * Check possibility and perform fix for unresolved references.
@@ -102,72 +101,49 @@ public class AutoImportFix(element: JetSimpleNameExpression) : JetHintAction<Jet
referenceName = conventionName.asString() referenceName = conventionName.asString()
} }
} }
if (referenceName.isEmpty()) return listOf() if (referenceName.isEmpty()) return listOf()
val resolveSessionForBodies = element.getLazyResolveSession() val resolveSession = element.getLazyResolveSession()
val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return listOf() val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return listOf()
val searchScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) val searchScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module)
val result = ArrayList<FqName>() val result = ArrayList<FqName>()
if (!isSuppressedTopLevelImportInPosition(element)) {
result.addAll(getClassNames(referenceName, file, searchScope, resolveSessionForBodies)) if (!element.isImportDirectiveExpression() && !JetPsiUtil.isSelectorInQualified(element)) {
result.addAll(getJetTopLevelFunctions(referenceName, element, searchScope, resolveSessionForBodies, file.getProject())) result.addAll(getClassNames(referenceName, file, searchScope))
result.addAll(getTopLevelFunctions(referenceName, element, searchScope, resolveSession, file.getProject()))
} }
result.addAll(getJetExtensionFunctions(referenceName, element, searchScope, resolveSessionForBodies, file.getProject())) result.addAll(getExtensionFunctions(referenceName, element, searchScope, resolveSession, file.getProject()))
return result.filter { ImportInsertHelper.needImport(ImportPath(it, false), file) } return result.filter { ImportInsertHelper.needImport(ImportPath(it, false), file) }
} }
private fun isSuppressedTopLevelImportInPosition(element: JetSimpleNameExpression) private fun getTopLevelFunctions(name: String, context: JetExpression, searchScope: GlobalSearchScope, resolveSession: ResolveSessionForBodies, project: Project): Collection<FqName>
= element.isImportDirectiveExpression() || JetPsiUtil.isSelectorInQualified(element) = KotlinIndicesHelper(project).getTopLevelFunctionDescriptorsByName(name, context, resolveSession, searchScope)
private fun getJetTopLevelFunctions(referenceName: String, context: JetExpression, searchScope: GlobalSearchScope, resolveSession: ResolveSessionForBodies, project: Project): Collection<FqName>
= KotlinIndicesHelper(project).getTopLevelFunctionDescriptorsByName(referenceName, context, resolveSession, searchScope)
.map { DescriptorUtils.getFqNameSafe(it) } .map { DescriptorUtils.getFqNameSafe(it) }
.toSet() .toSet()
private fun getJetExtensionFunctions(referenceName: String, expression: JetSimpleNameExpression, searchScope: GlobalSearchScope, resolveSession: ResolveSessionForBodies, project: Project): Collection<FqName> private fun getExtensionFunctions(name: String, expression: JetSimpleNameExpression, searchScope: GlobalSearchScope, resolveSession: ResolveSessionForBodies, project: Project): Collection<FqName>
= KotlinIndicesHelper(project).getCallableExtensions({ it == referenceName}, expression, resolveSession, searchScope) = KotlinIndicesHelper(project).getCallableExtensions({ it == name }, expression, resolveSession, searchScope)
.map { DescriptorUtils.getFqNameSafe(it) } .map { DescriptorUtils.getFqNameSafe(it) }
.toSet() .toSet()
/* private fun getClassNames(name: String, file: JetFile, searchScope: GlobalSearchScope): Collection<FqName>
* Searches for possible class names in kotlin context and java facade. = getShortNamesCache(file).getClassesByName(name, searchScope)
*/
private fun getClassNames(referenceName: String, file: JetFile, searchScope: GlobalSearchScope, analyzer: KotlinCodeAnalyzer): Collection<FqName> {
val possibleResolveNames = if (!ProjectStructureUtil.isJsKotlinModule(file)) {
getClassesFromCache(referenceName, searchScope, file)
}
else {
getJetClasses(referenceName, searchScope, file.getProject(), analyzer)
}
// TODO: Do appropriate sorting
return Lists.newArrayList<FqName>(possibleResolveNames)
}
private fun getClassesFromCache(typeName: String, searchScope: GlobalSearchScope, file: JetFile): Collection<FqName>
= getShortNamesCache(file).getClassesByName(typeName, searchScope)
.filter { JetPsiHeuristicsUtil.isAccessible(it, file) } .filter { JetPsiHeuristicsUtil.isAccessible(it, file) }
.map { FqName(it.getQualifiedName()!!) } .map { FqName(it.getQualifiedName()!!) }
.toSet() .toSet()
private fun getShortNamesCache(jetFile: JetFile): PsiShortNamesCache { private fun getShortNamesCache(jetFile: JetFile): PsiShortNamesCache {
if (ProjectStructureUtil.isJsKotlinModule(jetFile)) { // if we are in JS module, do not include non-kotlin classes
return JetShortNamesCache.getKotlinInstance(jetFile.getProject()) return if (ProjectStructureUtil.isJsKotlinModule(jetFile))
} JetShortNamesCache.getKotlinInstance(jetFile.getProject())
else
return PsiShortNamesCache.getInstance(jetFile.getProject()) PsiShortNamesCache.getInstance(jetFile.getProject())
} }
private fun getJetClasses(typeName: String, searchScope: GlobalSearchScope, project: Project, resolveSession: KotlinCodeAnalyzer): Collection<FqName>
= KotlinIndicesHelper(project).getClassDescriptorsByName(typeName, resolveSession, searchScope)
.map { DescriptorUtils.getFqNameSafe(it) }
.toSet()
class object { class object {
public fun createFactory(): JetSingleIntentionActionFactory { public fun createFactory(): JetSingleIntentionActionFactory {
return object : JetSingleIntentionActionFactory() { return object : JetSingleIntentionActionFactory() {