From 337eb883b36bb5121793d17e0e300575d409246d Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Mon, 24 Apr 2017 14:51:41 +0300 Subject: [PATCH] IDELightClassContexts: Use CallResolver to resolve relevant annotation calls Drop code that made decisions based on text Use CallResolver directly to avoid calling TypeResolver which only returns error types in ad hoc resolve --- .../kotlin/resolve/calls/CallResolver.java | 9 +++ .../lightClasses/IDELightClassContexts.kt | 79 +++++-------------- 2 files changed, 27 insertions(+), 61 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index c175b8bc776..4f3cf869fdc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -346,6 +346,15 @@ public class CallResolver { return checkArgumentTypesAndFail(context); } + return resolveConstructorCall(context, functionReference, constructedType); + } + + @NotNull + public OverloadResolutionResults resolveConstructorCall( + @NotNull BasicCallResolutionContext context, + @NotNull KtReferenceExpression functionReference, + @NotNull KotlinType constructedType + ) { Pair>, BasicCallResolutionContext> candidatesAndContext = prepareCandidatesAndContextForConstructorCall(constructedType, context); diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt index 52db3c828f0..581a69e441b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt @@ -30,8 +30,6 @@ import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.frontend.di.configureModule @@ -50,12 +48,12 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.calls.CallResolver -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall -import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument +import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext +import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode +import org.jetbrains.kotlin.resolve.calls.context.ContextDependency import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults -import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus -import org.jetbrains.kotlin.resolve.constants.ConstantValue -import org.jetbrains.kotlin.resolve.constants.StringValue +import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory +import org.jetbrains.kotlin.resolve.calls.util.CallMaker import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform @@ -68,6 +66,7 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.WrappedTypeFactory import org.jetbrains.kotlin.utils.sure @@ -275,21 +274,17 @@ object IDELightClassContexts { class AdHocAnnotationResolver( private val moduleDescriptor: ModuleDescriptor, - callResolver: CallResolver, + private val callResolver: CallResolver, constantExpressionEvaluator: ConstantExpressionEvaluator, storageManager: StorageManager ) : AnnotationResolverImpl(callResolver, constantExpressionEvaluator, storageManager) { - override fun resolveAnnotationEntries(scope: LexicalScope, annotationEntries: List, trace: BindingTrace, shouldResolveArguments: Boolean): Annotations { - return super.resolveAnnotationEntries(scope, annotationEntries, trace, shouldResolveArguments) - } - override fun resolveAnnotationType(scope: LexicalScope, entryElement: KtAnnotationEntry, trace: BindingTrace): KotlinType { return annotationClassByEntry(entryElement)?.defaultType ?: super.resolveAnnotationType(scope, entryElement, trace) } private fun annotationClassByEntry(entryElement: KtAnnotationEntry): ClassDescriptor? { - val annotationTypeReferencePsi = (entryElement.typeReference?.typeElement as? KtUserType)?.referenceExpression ?: return null + val annotationTypeReferencePsi = entryElement.calleeExpression?.constructorReferenceExpression ?: return null val referencedName = annotationTypeReferencePsi.getReferencedName() for (annotationFqName in annotationsThatAffectCodegen) { if (referencedName == annotationFqName.shortName().asString()) { @@ -304,56 +299,18 @@ object IDELightClassContexts { override fun resolveAnnotationCall(annotationEntry: KtAnnotationEntry, scope: LexicalScope, trace: BindingTrace): OverloadResolutionResults { val annotationConstructor = annotationClassByEntry(annotationEntry)?.constructors?.singleOrNull() ?: return super.resolveAnnotationCall(annotationEntry, scope, trace) - val valueArgumentText = valueArgumentText(annotationEntry) - ?: return super.resolveAnnotationCall(annotationEntry, scope, trace) - val fakeResolvedCall = object : ResolvedCall { - override fun getStatus() = ResolutionStatus.SUCCESS - override fun getCandidateDescriptor() = annotationConstructor - override fun getResultingDescriptor() = annotationConstructor - override fun getValueArguments() = - annotationConstructor.valueParameters.singleOrNull()?.let { mapOf(it to FakeResolvedValueArgument(valueArgumentText)) }.orEmpty() - override fun getCall() = notImplemented - override fun getExtensionReceiver() = notImplemented - override fun getDispatchReceiver() = notImplemented - override fun getExplicitReceiverKind() = notImplemented - - override fun getValueArgumentsByIndex() = notImplemented - override fun getArgumentMapping(valueArgument: ValueArgument) = notImplemented - override fun getTypeArguments() = notImplemented - override fun getDataFlowInfoForArguments() = notImplemented - override fun getSmartCastDispatchReceiverType() = notImplemented - } - - return object : OverloadResolutionResults { - override fun isSingleResult() = true - override fun getResultingCall(): ResolvedCall = fakeResolvedCall - override fun getResultingDescriptor() = annotationConstructor - override fun getAllCandidates() = notImplemented - override fun getResultingCalls() = notImplemented - override fun getResultCode() = notImplemented - override fun isSuccess() = notImplemented - override fun isNothing() = notImplemented - override fun isAmbiguity() = notImplemented - override fun isIncomplete() = notImplemented - } - } - - private fun valueArgumentText(annotationEntry: KtAnnotationEntry) = - ((annotationEntry.valueArguments.singleOrNull()?.getArgumentExpression() as? KtStringTemplateExpression)?.entries?.singleOrNull() as? KtLiteralStringTemplateEntry)?.text - - override fun getAnnotationArgumentValue(trace: BindingTrace, valueParameter: ValueParameterDescriptor, resolvedArgument: ResolvedValueArgument): ConstantValue<*>? { - if (resolvedArgument is FakeResolvedValueArgument) return StringValue(resolvedArgument.argumentText, moduleDescriptor.builtIns) - - return super.getAnnotationArgumentValue(trace, valueParameter, resolvedArgument) - } - - private class FakeResolvedValueArgument(val argumentText: String) : ResolvedValueArgument { - override fun getArguments() = notImplemented + @Suppress("UNCHECKED_CAST") + return callResolver.resolveConstructorCall( + BasicCallResolutionContext.create( + trace, scope, CallMaker.makeCall(null, null, annotationEntry), TypeUtils.NO_EXPECTED_TYPE, + DataFlowInfoFactory.EMPTY, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, + true + ), + annotationEntry.calleeExpression!!.constructorReferenceExpression!!, + annotationConstructor.returnType + ) as OverloadResolutionResults } } - - private val notImplemented: Nothing - get() = error("Should not be called") }