This commit is contained in:
Valentin Kipyatkov
2015-09-30 14:00:50 +03:00
parent 56bb8adfd0
commit c12520da7f
7 changed files with 114 additions and 95 deletions
@@ -20,18 +20,11 @@ package org.jetbrains.kotlin.idea.codeInsight
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.idea.util.ShadowedDeclarationsFilter
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.idea.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.psi.psiUtil.isImportDirectiveExpression
import org.jetbrains.kotlin.psi.psiUtil.isPackageDirectiveExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
@@ -51,59 +44,6 @@ import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
public data class CallTypeAndReceiver(
val callType: CallType,
val receiver: JetElement?
) {
companion object {
public fun detect(expression: JetSimpleNameExpression): CallTypeAndReceiver {
val parent = expression.parent
if (parent is JetCallableReferenceExpression) {
return CallTypeAndReceiver(CallType.CALLABLE_REFERENCE, parent.typeReference)
}
val receiverExpression = expression.getReceiverExpression()
if (expression.isImportDirectiveExpression()) {
return CallTypeAndReceiver(CallType.IMPORT_DIRECTIVE, receiverExpression)
}
if (expression.isPackageDirectiveExpression()) {
return CallTypeAndReceiver(CallType.PACKAGE_DIRECTIVE, receiverExpression)
}
if (receiverExpression == null) {
return CallTypeAndReceiver(CallType.NORMAL, null)
}
val callType = when (parent) {
is JetBinaryExpression -> CallType.INFIX
is JetCallExpression -> {
if ((parent.getParent() as JetQualifiedExpression).getOperationSign() == JetTokens.SAFE_ACCESS)
CallType.SAFE
else
CallType.NORMAL
}
is JetQualifiedExpression -> {
if (parent.getOperationSign() == JetTokens.SAFE_ACCESS)
CallType.SAFE
else
CallType.NORMAL
}
is JetUnaryExpression -> CallType.UNARY
is JetUserType -> CallType.NORMAL
else -> error("Unknown parent for expression with receiver: $parent")
}
return CallTypeAndReceiver(callType, receiverExpression)
}
}
}
public class ReferenceVariantsHelper(
private val context: BindingContext,
private val resolutionFacade: ResolutionFacade,
@@ -0,0 +1,110 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.util
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.psi.psiUtil.isImportDirectiveExpression
import org.jetbrains.kotlin.psi.psiUtil.isPackageDirectiveExpression
public enum class CallType {
NORMAL,
SAFE,
INFIX {
override fun canCall(descriptor: DeclarationDescriptor)
= descriptor is SimpleFunctionDescriptor && descriptor.getValueParameters().size() == 1
},
UNARY {
override fun canCall(descriptor: DeclarationDescriptor)
= descriptor is SimpleFunctionDescriptor && descriptor.getValueParameters().size() == 0
},
CALLABLE_REFERENCE {
// currently callable references to locals and parameters are not supported
override fun canCall(descriptor: DeclarationDescriptor)
= descriptor is FunctionDescriptor || descriptor is PropertyDescriptor
},
//TODO: canCall
IMPORT_DIRECTIVE,
PACKAGE_DIRECTIVE
;
public open fun canCall(descriptor: DeclarationDescriptor): Boolean = true
}
public data class CallTypeAndReceiver(
val callType: CallType,
val receiver: JetElement?
) {
companion object {
public fun detect(expression: JetSimpleNameExpression): CallTypeAndReceiver {
val parent = expression.parent
if (parent is JetCallableReferenceExpression) {
return CallTypeAndReceiver(CallType.CALLABLE_REFERENCE, parent.typeReference)
}
val receiverExpression = expression.getReceiverExpression()
if (expression.isImportDirectiveExpression()) {
return CallTypeAndReceiver(CallType.IMPORT_DIRECTIVE, receiverExpression)
}
if (expression.isPackageDirectiveExpression()) {
return CallTypeAndReceiver(CallType.PACKAGE_DIRECTIVE, receiverExpression)
}
if (receiverExpression == null) {
return CallTypeAndReceiver(CallType.NORMAL, null)
}
val callType = when (parent) {
is JetBinaryExpression -> CallType.INFIX
is JetCallExpression -> {
if ((parent.getParent() as JetQualifiedExpression).getOperationSign() == JetTokens.SAFE_ACCESS)
CallType.SAFE
else
CallType.NORMAL
}
is JetQualifiedExpression -> {
if (parent.getOperationSign() == JetTokens.SAFE_ACCESS)
CallType.SAFE
else
CallType.NORMAL
}
is JetUnaryExpression -> CallType.UNARY
is JetUserType -> CallType.NORMAL
else -> error("Unknown parent for expression with receiver: $parent")
}
return CallTypeAndReceiver(callType, receiverExpression)
}
}
}
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.idea.util
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.codeInsight.CallTypeAndReceiver
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
@@ -33,36 +33,6 @@ import org.jetbrains.kotlin.types.typeUtil.TypeNullability
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.nullability
public enum class CallType {
NORMAL,
SAFE,
INFIX {
override fun canCall(descriptor: DeclarationDescriptor)
= descriptor is SimpleFunctionDescriptor && descriptor.getValueParameters().size() == 1
},
UNARY {
override fun canCall(descriptor: DeclarationDescriptor)
= descriptor is SimpleFunctionDescriptor && descriptor.getValueParameters().size() == 0
},
CALLABLE_REFERENCE {
// currently callable references to locals and parameters are not supported
override fun canCall(descriptor: DeclarationDescriptor)
= descriptor is FunctionDescriptor || descriptor is PropertyDescriptor
},
//TODO: canCall
IMPORT_DIRECTIVE,
PACKAGE_DIRECTIVE
;
public open fun canCall(descriptor: DeclarationDescriptor): Boolean = true
}
public fun CallableDescriptor.substituteExtensionIfCallable(
receivers: Collection<ReceiverValue>,
context: BindingContext,
@@ -29,7 +29,6 @@ import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getResolveScope
import org.jetbrains.kotlin.idea.codeInsight.CallTypeAndReceiver
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
import org.jetbrains.kotlin.idea.core.*
@@ -37,6 +36,7 @@ import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
import org.jetbrains.kotlin.idea.util.ShadowedDeclarationsFilter
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
import org.jetbrains.kotlin.name.Name
@@ -21,9 +21,9 @@ import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.completion.CompletionSorter
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.codeInsight.CallTypeAndReceiver
import org.jetbrains.kotlin.idea.completion.*
import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptorKindExclude
import org.jetbrains.kotlin.psi.FunctionLiteralArgument
import org.jetbrains.kotlin.psi.JetCodeFragment
@@ -22,12 +22,12 @@ import com.intellij.psi.search.PsiShortNamesCache
import com.intellij.psi.stubs.StringStubIndexExtension
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.codeInsight.CallTypeAndReceiver
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.stubindex.*
import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable
import org.jetbrains.kotlin.name.FqName