Create descriptors for parameters inside parameter list of KtFunctionType
Do not throw when trying to resolveToDescriptor those parameters
This commit is contained in:
@@ -20,24 +20,25 @@ import com.intellij.util.SmartList
|
|||||||
import org.jetbrains.kotlin.context.TypeLazinessToken
|
import org.jetbrains.kotlin.context.TypeLazinessToken
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.debugTypeInfo
|
import org.jetbrains.kotlin.psi.codeFragmentUtil.debugTypeInfo
|
||||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||||
import org.jetbrains.kotlin.resolve.PossiblyBareType.type
|
import org.jetbrains.kotlin.resolve.PossiblyBareType.type
|
||||||
import org.jetbrains.kotlin.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider
|
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScope
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScope
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallableDescriptors
|
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallableDescriptors
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||||
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
|
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
|
||||||
import org.jetbrains.kotlin.resolve.scopes.LazyScopeAdapter
|
import org.jetbrains.kotlin.resolve.scopes.LazyScopeAdapter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
||||||
|
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
@@ -196,18 +197,61 @@ class TypeResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionType(type: KtFunctionType) {
|
override fun visitFunctionType(type: KtFunctionType) {
|
||||||
val receiverTypeRef = type.getReceiverTypeReference()
|
val receiverTypeRef = type.receiverTypeReference
|
||||||
type.parameters.forEach { identifierChecker.checkDeclaration(it, c.trace) }
|
|
||||||
val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
||||||
|
|
||||||
type.parameters.forEach { checkParameterInFunctionType(it) }
|
val parameterDescriptors = resolveParametersOfFunctionType(type.parameters)
|
||||||
val parameterTypes = type.getParameters().map { resolveType(c.noBareTypes(), it.getTypeReference()!!) }
|
|
||||||
|
|
||||||
val returnTypeRef = type.getReturnTypeReference()
|
val returnTypeRef = type.returnTypeReference
|
||||||
val returnType = if (returnTypeRef != null)
|
val returnType = if (returnTypeRef != null) resolveType(c.noBareTypes(), returnTypeRef)
|
||||||
resolveType(c.noBareTypes(), returnTypeRef)
|
|
||||||
else moduleDescriptor.builtIns.unitType
|
else moduleDescriptor.builtIns.unitType
|
||||||
result = type(moduleDescriptor.builtIns.getFunctionType(annotations, receiverType, parameterTypes, returnType))
|
|
||||||
|
result = type(
|
||||||
|
moduleDescriptor.builtIns.getFunctionType(
|
||||||
|
annotations, receiverType, parameterDescriptors.map { it.type }, returnType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveParametersOfFunctionType(parameters: List<KtParameter>): List<VariableDescriptor> {
|
||||||
|
class ParameterOfFunctionTypeDescriptor(
|
||||||
|
containingDeclaration: DeclarationDescriptor,
|
||||||
|
annotations: Annotations,
|
||||||
|
name: Name,
|
||||||
|
type: KotlinType,
|
||||||
|
source: SourceElement
|
||||||
|
) : VariableDescriptorImpl(containingDeclaration, annotations, name, type, source) {
|
||||||
|
override fun getVisibility() = Visibilities.LOCAL
|
||||||
|
|
||||||
|
override fun substitute(substitutor: TypeSubstitutor): VariableDescriptor? {
|
||||||
|
throw UnsupportedOperationException("Should not be called for descriptor of type $javaClass")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isVar() = false
|
||||||
|
|
||||||
|
override fun getCompileTimeInitializer() = null
|
||||||
|
|
||||||
|
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
|
||||||
|
return visitor.visitVariableDescriptor(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters.forEach {
|
||||||
|
identifierChecker.checkDeclaration(it, c.trace)
|
||||||
|
checkParameterInFunctionType(it)
|
||||||
|
}
|
||||||
|
return parameters.map { parameter ->
|
||||||
|
val parameterType = resolveType(c.noBareTypes(), parameter.typeReference!!)
|
||||||
|
val descriptor = ParameterOfFunctionTypeDescriptor(
|
||||||
|
c.scope.ownerDescriptor,
|
||||||
|
Annotations.EMPTY,
|
||||||
|
parameter.nameAsSafeName,
|
||||||
|
parameterType,
|
||||||
|
parameter.toSourceElement()
|
||||||
|
)
|
||||||
|
c.trace.record(BindingContext.VALUE_PARAMETER, parameter, descriptor)
|
||||||
|
descriptor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDynamicType(type: KtDynamicType) {
|
override fun visitDynamicType(type: KtDynamicType) {
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ package org.jetbrains.kotlin.idea
|
|||||||
|
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
|
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||||
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -300,4 +302,19 @@ class C(param1: String = "", param2: Int = 0) {
|
|||||||
val fileAnnotationList = file.fileAnnotationList!!
|
val fileAnnotationList = file.fileAnnotationList!!
|
||||||
fileAnnotationList.analyze(BodyResolveMode.PARTIAL)
|
fileAnnotationList.analyze(BodyResolveMode.PARTIAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testNamedParametersInFunctionType() {
|
||||||
|
val file = myFixture.configureByText("Test.kt", """
|
||||||
|
fun <K, V> intercept(block: (key: K, next: (K) -> V, K) -> V) {}
|
||||||
|
""") as KtFile
|
||||||
|
|
||||||
|
val function = file.declarations[0] as KtNamedFunction
|
||||||
|
val functionType = function.valueParameters.first().typeReference!!.typeElement as KtFunctionType
|
||||||
|
val descriptorsForParameters = functionType.parameters.map { it.resolveToDescriptor() }
|
||||||
|
|
||||||
|
assert(
|
||||||
|
listOf("key", "next", SpecialNames.NO_NAME_PROVIDED.asString()) ==
|
||||||
|
descriptorsForParameters.map { it.name.asString() }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user