[NI] Support callable reference resolution in NI.
Missing parts: - report results about callable references into trace
This commit is contained in:
committed by
Mikhail Zarechenskiy
parent
02f4558683
commit
55dc2c11f7
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.LambdaKotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
@@ -110,8 +110,8 @@ class CallableReferenceKotlinCallArgumentImpl(
|
||||
override val dataFlowInfoAfterThisArgument: DataFlowInfo,
|
||||
val ktCallableReferenceExpression: KtCallableReferenceExpression,
|
||||
override val argumentName: Name?,
|
||||
override val lhsType: UnwrappedType?,
|
||||
override val constraintStorage: ConstraintStorage
|
||||
override val lhsResult: LHSResult,
|
||||
override val rhsName: Name
|
||||
) : CallableReferenceKotlinCallArgument, PSIKotlinCallArgument()
|
||||
|
||||
class SubKotlinCallArgumentImpl(
|
||||
@@ -137,6 +137,16 @@ class ExpressionKotlinCallArgumentImpl(
|
||||
override val isSafeCall: Boolean get() = false
|
||||
}
|
||||
|
||||
class FakeValueArgumentForLeftCallableReference(val ktExpression: KtCallableReferenceExpression): ValueArgument {
|
||||
override fun getArgumentExpression() = ktExpression.receiverExpression
|
||||
|
||||
override fun getArgumentName(): ValueArgumentName? = null
|
||||
override fun isNamed(): Boolean = false
|
||||
override fun asElement(): KtElement = getArgumentExpression() ?: ktExpression
|
||||
override fun getSpreadElement(): LeafPsiElement? = null
|
||||
override fun isExternal(): Boolean = false
|
||||
}
|
||||
|
||||
internal fun createSimplePSICallArgument(
|
||||
context: BasicCallResolutionContext,
|
||||
valueArgument: ValueArgument,
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
@@ -28,9 +30,10 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.ModifierCheckerCore
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.TypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode
|
||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
import org.jetbrains.kotlin.resolve.calls.components.ArgumentsToParametersMapper
|
||||
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceResolver
|
||||
@@ -40,7 +43,6 @@ import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.results.*
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
@@ -75,6 +77,7 @@ class PSICallResolver(
|
||||
val resultTypeResolver: ResultTypeResolver,
|
||||
val callableReferenceResolver: CallableReferenceResolver,
|
||||
val constraintInjector: ConstraintInjector,
|
||||
val reflectionTypes: ReflectionTypes,
|
||||
private val kotlinToResolvedCallTransformer: KotlinToResolvedCallTransformer,
|
||||
private val kotlinCallResolver: KotlinCallResolver,
|
||||
private val typeApproximator: TypeApproximator,
|
||||
@@ -146,7 +149,7 @@ class PSICallResolver(
|
||||
|
||||
private fun createCallContext(scopeTower: ASTScopeTower, resolutionCallbacks: KotlinResolutionCallbacks) =
|
||||
KotlinCallContext(scopeTower, resolutionCallbacks, argumentsToParametersMapper, typeArgumentsToParametersMapper, resultTypeResolver,
|
||||
callableReferenceResolver, constraintInjector)
|
||||
callableReferenceResolver, constraintInjector, reflectionTypes)
|
||||
|
||||
private fun <D : CallableDescriptor> convertToOverloadResolutionResults(
|
||||
context: BasicCallResolutionContext,
|
||||
@@ -456,17 +459,44 @@ class PSICallResolver(
|
||||
if (ktExpression is KtCallableReferenceExpression) {
|
||||
checkNoSpread(outerCallContext, valueArgument)
|
||||
|
||||
// todo analyze left expression and get constraint system
|
||||
val (lhsResult, rightResults) = doubleColonExpressionResolver.resolveCallableReference(
|
||||
ktExpression, ExpressionTypingContext.newContext(context), ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS)
|
||||
|
||||
val expressionTypingContext = ExpressionTypingContext.newContext(context)
|
||||
val lhsResult = if (ktExpression.isEmptyLHS) null else doubleColonExpressionResolver.resolveDoubleColonLHS(ktExpression, expressionTypingContext)
|
||||
val newDataFlowInfo = (lhsResult as? DoubleColonLHS.Expression)?.dataFlowInfo ?: startDataFlowInfo
|
||||
val name = ktExpression.callableReference.getReferencedNameAsName()
|
||||
|
||||
// todo ChosenCallableReferenceDescriptor
|
||||
val lhsNewResult = when (lhsResult) {
|
||||
null -> LHSResult.Empty
|
||||
is DoubleColonLHS.Expression -> {
|
||||
if (lhsResult.isObjectQualifier) {
|
||||
val classifier = lhsResult.type.constructor.declarationDescriptor
|
||||
val calleeExpression = ktExpression.receiverExpression?.getCalleeExpressionIfAny()
|
||||
if (calleeExpression is KtSimpleNameExpression && classifier is ClassDescriptor) {
|
||||
LHSResult.Object(ClassQualifier(calleeExpression, classifier))
|
||||
}
|
||||
else {
|
||||
LHSResult.Empty // this is error case actually
|
||||
}
|
||||
}
|
||||
else {
|
||||
val fakeArgument = FakeValueArgumentForLeftCallableReference(ktExpression)
|
||||
|
||||
val kotlinCallArgument = createSimplePSICallArgument(context, fakeArgument, lhsResult.typeInfo)
|
||||
kotlinCallArgument?.let { LHSResult.Expression(it as SimpleKotlinCallArgument) } ?: LHSResult.Empty
|
||||
}
|
||||
}
|
||||
is DoubleColonLHS.Type -> {
|
||||
val qualifier = expressionTypingContext.trace.get(BindingContext.QUALIFIER, ktExpression.receiverExpression!!)
|
||||
if (qualifier is ClassQualifier) {
|
||||
LHSResult.Type(qualifier)
|
||||
}
|
||||
else {
|
||||
LHSResult.Empty // this is error case actually
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CallableReferenceKotlinCallArgumentImpl(valueArgument, startDataFlowInfo, newDataFlowInfo,
|
||||
ktExpression, argumentName, (lhsResult as? DoubleColonLHS.Type)?.type?.unwrap(),
|
||||
ConstraintStorage.Empty)
|
||||
ktExpression, argumentName, lhsNewResult, name)
|
||||
}
|
||||
|
||||
// valueArgument.getArgumentExpression()!! instead of ktExpression is hack -- type info should be stored also for parenthesized expression
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* 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.types.expressions;
|
||||
|
||||
public enum CoercionStrategy {
|
||||
NO_COERCION,
|
||||
COERCION_TO_UNIT
|
||||
}
|
||||
+1
-1
@@ -75,7 +75,7 @@ sealed class DoubleColonLHS(val type: KotlinType) {
|
||||
* (Obj)::class // not an object qualifier (can only be treated as an expression, not as a type)
|
||||
* { Obj }()::class // not an object qualifier
|
||||
*/
|
||||
class Expression(typeInfo: KotlinTypeInfo, val isObjectQualifier: Boolean) : DoubleColonLHS(typeInfo.type!!) {
|
||||
class Expression(val typeInfo: KotlinTypeInfo, val isObjectQualifier: Boolean) : DoubleColonLHS(typeInfo.type!!) {
|
||||
val dataFlowInfo: DataFlowInfo = typeInfo.dataFlowInfo
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user