diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/JetMultiDeclarationReference.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/JetMultiDeclarationReference.kt index 8f993e09e37..a601e098e63 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/JetMultiDeclarationReference.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/JetMultiDeclarationReference.kt @@ -23,6 +23,7 @@ import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import com.intellij.util.IncorrectOperationException import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.analyze class JetMultiDeclarationReference(element: JetMultiDeclaration) : JetMultiReference(element) { override fun getTargetDescriptors(context: BindingContext): Collection { @@ -39,7 +40,8 @@ class JetMultiDeclarationReference(element: JetMultiDeclaration) : JetMultiRefer } override fun canRename(): Boolean { - return resolveToDescriptors().all { it is CallableMemberDescriptor && it.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED} + val bindingContext = expression.analyze() //TODO: should it use full body resolve? + return resolveToDescriptors(bindingContext).all { it is CallableMemberDescriptor && it.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED} } override fun handleElementRename(newElementName: String?): PsiElement? { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/JetReference.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/JetReference.kt index 502974fa20e..6c17c9b721d 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/JetReference.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/JetReference.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList public trait JetReference : PsiPolyVariantReference { - public fun resolveToDescriptors(): Collection + public fun resolveToDescriptors(bindingContext: BindingContext): Collection } public abstract class AbstractJetReference(element: T) @@ -72,8 +72,8 @@ public abstract class AbstractJetReference(element: T) return resolveToPsiElements(bindingContext, getTargetDescriptors(bindingContext)) } - override fun resolveToDescriptors(): Collection { - return getTargetDescriptors(expression.analyze()) + override fun resolveToDescriptors(bindingContext: BindingContext): Collection { + return getTargetDescriptors(bindingContext) } private fun resolveToPsiElements(context: BindingContext, targetDescriptors: Collection): Collection { diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt index 1e0f42e295f..1be41df7c50 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinCopyPasteReferenceProcessor.kt @@ -119,7 +119,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor && descriptors.size() > 1) return listOf() @@ -231,7 +231,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor by Delegates.notNull() protected fun getReferenceVariants(kindFilter: DescriptorKindFilter, runtimeReceiverType: Boolean): Collection { - val descriptors = referenceVariantsHelper!!.getReferenceVariants(reference!!.expression, kindFilter, runtimeReceiverType, prefixMatcher.asNameFilter()) + val descriptors = referenceVariantsHelper.getReferenceVariants(reference!!.expression, kindFilter, runtimeReceiverType, prefixMatcher.asNameFilter()) if (!runtimeReceiverType) { if (position.getContainingFile() is JetCodeFragment) { alreadyAddedDescriptors = descriptors @@ -229,7 +227,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess protected fun addAllClasses(kindFilter: (ClassKind) -> Boolean) { AllClassesCompletion( - parameters, lookupElementFactory, resolutionFacade, bindingContext!!, moduleDescriptor, + parameters, lookupElementFactory, resolutionFacade, bindingContext, moduleDescriptor, searchScope, prefixMatcher, kindFilter, { isVisibleDescriptor(it) } ).collect(collector) } @@ -311,7 +309,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration, // if "this" is parsed correctly in the current context - insert it and all this@xxx items "this" -> { if (expression != null) { - collector.addElements(thisExpressionItems(bindingContext!!, expression, prefix).map { it.factory() }) + collector.addElements(thisExpressionItems(bindingContext, expression, prefix).map { it.factory() }) } else { // for completion in secondary constructor delegation call @@ -322,7 +320,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration, // if "return" is parsed correctly in the current context - insert it and all return@xxx items "return" -> { if (expression != null) { - collector.addElements(returnExpressionItems(bindingContext!!, expression)) + collector.addElements(returnExpressionItems(bindingContext, expression)) } } @@ -351,7 +349,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration, } } - NamedParametersCompletion.complete(position, collector) + NamedParametersCompletion.complete(position, collector, bindingContext) } private object NonAnnotationClassifierExclude : DescriptorKindExclude { @@ -400,7 +398,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para if (expression != null) { val mapper = ToFromOriginalFileMapper(parameters.getOriginalFile() as JetFile, position.getContainingFile() as JetFile, parameters.getOffset()) val completion = SmartCompletion(expression, resolutionFacade, moduleDescriptor, - bindingContext!!, { isVisibleDescriptor(it) }, inDescriptor, prefixMatcher, originalSearchScope, + bindingContext, { isVisibleDescriptor(it) }, inDescriptor, prefixMatcher, originalSearchScope, mapper, lookupElementFactory) val result = completion.execute() if (result != null) { diff --git a/idea/src/org/jetbrains/kotlin/idea/completion/NamedParametersCompletion.kt b/idea/src/org/jetbrains/kotlin/idea/completion/NamedParametersCompletion.kt index d73d9518bbe..a4b742113a2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/completion/NamedParametersCompletion.kt +++ b/idea/src/org/jetbrains/kotlin/idea/completion/NamedParametersCompletion.kt @@ -16,30 +16,31 @@ package org.jetbrains.kotlin.idea.completion -import org.jetbrains.kotlin.psi.JetValueArgument -import org.jetbrains.kotlin.lexer.JetTokens -import org.jetbrains.kotlin.psi.JetCallElement -import org.jetbrains.kotlin.idea.references.JetReference -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import com.intellij.codeInsight.lookup.LookupElementBuilder -import org.jetbrains.kotlin.idea.JetIcons -import org.jetbrains.kotlin.idea.quickfix.QuickFixUtil -import org.jetbrains.kotlin.renderer.DescriptorRenderer -import com.intellij.codeInsight.lookup.LookupElement -import com.intellij.codeInsight.completion.InsertionContext -import com.intellij.psi.filters.AndFilter -import org.jetbrains.kotlin.psi.JetValueArgumentName -import com.intellij.psi.filters.position.ParentElementFilter -import com.intellij.psi.filters.OrFilter -import com.intellij.psi.filters.ClassFilter -import org.jetbrains.kotlin.idea.util.FirstChildInParentFilter -import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression -import com.intellij.psi.PsiElement import com.intellij.codeInsight.completion.InsertHandler -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import com.intellij.codeInsight.completion.InsertionContext +import com.intellij.codeInsight.lookup.LookupElement +import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.psi.PsiElement +import com.intellij.psi.filters.AndFilter +import com.intellij.psi.filters.ClassFilter +import com.intellij.psi.filters.OrFilter +import com.intellij.psi.filters.position.ParentElementFilter +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.idea.JetIcons import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler +import org.jetbrains.kotlin.idea.quickfix.QuickFixUtil +import org.jetbrains.kotlin.idea.references.JetReference +import org.jetbrains.kotlin.idea.util.FirstChildInParentFilter +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.lexer.JetTokens +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.JetCallElement +import org.jetbrains.kotlin.psi.JetValueArgument +import org.jetbrains.kotlin.psi.JetValueArgumentName +import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.resolve.BindingContext object NamedParametersCompletion { private val positionFilter = AndFilter( @@ -68,7 +69,7 @@ object NamedParametersCompletion { return false } - public fun complete(position: PsiElement, collector: LookupElementsCollector) { + public fun complete(position: PsiElement, collector: LookupElementsCollector, bindingContext: BindingContext) { if (!positionFilter.isAcceptable(position, position)) return val valueArgument = position.getStrictParentOfType()!! @@ -78,7 +79,7 @@ object NamedParametersCompletion { val callReference = callSimpleName.getReference() as JetReference - val functionDescriptors = callReference.resolveToDescriptors().map { it as? FunctionDescriptor }.filterNotNull() + val functionDescriptors = callReference.resolveToDescriptors(bindingContext).map { it as? FunctionDescriptor }.filterNotNull() for (funDescriptor in functionDescriptors) { if (!funDescriptor.hasStableParameterNames()) continue diff --git a/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt b/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt index da53497a31e..d239b41a4a5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt @@ -182,19 +182,15 @@ public class KotlinImportOptimizer() : ImportOptimizer { override fun visitPackageDirective(directive: JetPackageDirective) { } - - private fun JetElement.classForCompanionObjectReference(): ClassDescriptor? { - return analyze()[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, this as? JetReferenceExpression] - } - override fun visitJetElement(element: JetElement) { val reference = element.getReference() if (reference is JetReference) { val referencedName = (element as? JetNameReferenceExpression)?.getReferencedNameAsName() //TODO: other types of references + val bindingContext = element.analyze() //class qualifiers that refer to companion objects should be considered (containing) class references - val targets = element.classForCompanionObjectReference()?.let { listOf(it) } - ?: reference.resolveToDescriptors() + val targets = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, element as? JetReferenceExpression]?.let { listOf(it) } + ?: reference.resolveToDescriptors(bindingContext) for (target in targets) { if (!target.canBeReferencedViaImport()) continue if (target is PackageViewDescriptor && target.getFqName().parent() == FqName.ROOT) continue // no need to import top-level packages diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceExplicitFunctionLiteralParamWithItIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceExplicitFunctionLiteralParamWithItIntention.kt index ea86e612953..f4b95af4d3f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceExplicitFunctionLiteralParamWithItIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceExplicitFunctionLiteralParamWithItIntention.kt @@ -20,16 +20,18 @@ import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement +import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.util.PsiTreeUtil import com.intellij.refactoring.rename.RenameProcessor import com.intellij.usageView.UsageInfo -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.idea.JetBundle -import com.intellij.psi.codeStyle.CodeStyleManager -import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor -import org.jetbrains.kotlin.idea.references.JetReference import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor +import org.jetbrains.kotlin.idea.JetBundle +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.references.JetReference +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode public class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBaseIntentionAction() { override fun invoke(project: Project, editor: Editor, element: PsiElement) { @@ -73,7 +75,7 @@ public class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBa } is JetSimpleNameExpression -> { val reference = expression.getReference() as JetReference? - val variableDescriptor = reference?.resolveToDescriptors()?.firstOrNull() as? VariableDescriptor? + val variableDescriptor = reference?.resolveToDescriptors(expression.analyze(BodyResolveMode.PARTIAL))?.firstOrNull() as? VariableDescriptor? if (variableDescriptor != null) { val containingDescriptor = variableDescriptor.getContainingDeclaration() if (containingDescriptor is AnonymousFunctionDescriptor) { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt index e228bc1fc0e..544c42bae7b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt @@ -22,24 +22,25 @@ import com.intellij.openapi.project.Project import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.idea.JetBundle +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.references.JetReference +import org.jetbrains.kotlin.psi.JetFunctionLiteral import org.jetbrains.kotlin.psi.JetFunctionLiteralExpression import org.jetbrains.kotlin.psi.JetPsiFactory -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.idea.JetBundle import org.jetbrains.kotlin.psi.JetSimpleNameExpression -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.psi.JetFunctionLiteral -import org.jetbrains.kotlin.idea.references.JetReference -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode public class ReplaceItWithExplicitFunctionLiteralParamIntention() : PsiElementBaseIntentionAction() { override fun invoke(project: Project, editor: Editor, element: PsiElement) { val simpleNameExpression = element.getStrictParentOfType()!! val simpleNameReference = simpleNameExpression.getReference() as JetReference? - val target = simpleNameReference?.resolveToDescriptors()?.first()!! + val target = simpleNameReference?.resolveToDescriptors(simpleNameExpression.analyze(BodyResolveMode.PARTIAL))?.first()!! val funcExpr = DescriptorToSourceUtils.descriptorToDeclaration(target.getContainingDeclaration()!!) as JetFunctionLiteral @@ -74,9 +75,9 @@ public class ReplaceItWithExplicitFunctionLiteralParamIntention() : PsiElementBa return false } - val bindingContext = simpleNameExpression.analyze() + val bindingContext = simpleNameExpression.analyze(BodyResolveMode.PARTIAL) val reference = simpleNameExpression.getReference() as JetReference? - val simpleNameTarget = reference?.resolveToDescriptors()?.firstOrNull() as? ValueParameterDescriptor? + val simpleNameTarget = reference?.resolveToDescriptors(bindingContext)?.firstOrNull() as? ValueParameterDescriptor? if (simpleNameTarget == null || bindingContext.get(BindingContext.AUTO_CREATED_IT, simpleNameTarget) != true) { return false }