Build proper modifier list stubs for 'SuspendFunction$n<...>' types.
This commit is contained in:
committed by
Stanislav Erokhin
parent
cf4fb1eb25
commit
9dc458375a
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
||||||
@@ -72,6 +73,12 @@ val KotlinType.isBuiltinFunctionalType: Boolean
|
|||||||
kind == FunctionClassDescriptor.Kind.SuspendFunction
|
kind == FunctionClassDescriptor.Kind.SuspendFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isBuiltinFunctionClass(classId: ClassId): Boolean {
|
||||||
|
val kind = classId.asSingleFqName().toUnsafe().getFunctionalClassKind()
|
||||||
|
return kind == FunctionClassDescriptor.Kind.Function ||
|
||||||
|
kind == FunctionClassDescriptor.Kind.SuspendFunction
|
||||||
|
}
|
||||||
|
|
||||||
val KotlinType.isNonExtensionFunctionType: Boolean
|
val KotlinType.isNonExtensionFunctionType: Boolean
|
||||||
get() = isBuiltinFunctionalType && !isTypeAnnotatedWithExtensionFunctionType
|
get() = isBuiltinFunctionalType && !isTypeAnnotatedWithExtensionFunctionType
|
||||||
|
|
||||||
@@ -99,8 +106,12 @@ fun DeclarationDescriptor.getFunctionalClassKind(): FunctionClassDescriptor.Kind
|
|||||||
if (this !is ClassDescriptor) return null
|
if (this !is ClassDescriptor) return null
|
||||||
|
|
||||||
val fqNameUnsafe = this.fqNameUnsafe
|
val fqNameUnsafe = this.fqNameUnsafe
|
||||||
if (!fqNameUnsafe.isSafe || fqNameUnsafe.isRoot) return null
|
return fqNameUnsafe.getFunctionalClassKind()
|
||||||
val fqName = fqNameUnsafe.toSafe()
|
}
|
||||||
|
|
||||||
|
fun FqNameUnsafe.getFunctionalClassKind(): FunctionClassDescriptor.Kind? {
|
||||||
|
if (!isSafe || isRoot) return null
|
||||||
|
val fqName = toSafe()
|
||||||
|
|
||||||
return BuiltInFictitiousFunctionClassFactory.getFunctionalClassKind(fqName.shortName().asString(), fqName.parent())
|
return BuiltInFictitiousFunctionClassFactory.getFunctionalClassKind(fqName.shortName().asString(), fqName.parent())
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-5
@@ -19,7 +19,9 @@ package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.stubs.StubElement
|
import com.intellij.psi.stubs.StubElement
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.isNumberedFunctionClassFqName
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||||
|
import org.jetbrains.kotlin.builtins.isBuiltinFunctionClass
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.load.java.ANNOTATIONS_COPIED_TO_TYPES
|
import org.jetbrains.kotlin.load.java.ANNOTATIONS_COPIED_TO_TYPES
|
||||||
@@ -89,7 +91,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val classId = c.nameResolver.getClassId(if (type.hasClassName()) type.className else type.typeAliasName)
|
val classId = c.nameResolver.getClassId(if (type.hasClassName()) type.className else type.typeAliasName)
|
||||||
val shouldBuildAsFunctionType = isNumberedFunctionClassFqName(classId.asSingleFqName().toUnsafe())
|
val shouldBuildAsFunctionType = isBuiltinFunctionClass(classId)
|
||||||
&& type.argumentList.none { it.projection == Projection.STAR }
|
&& type.argumentList.none { it.projection == Projection.STAR }
|
||||||
if (shouldBuildAsFunctionType) {
|
if (shouldBuildAsFunctionType) {
|
||||||
val (extensionAnnotations, notExtensionAnnotations) =
|
val (extensionAnnotations, notExtensionAnnotations) =
|
||||||
@@ -114,13 +116,24 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createTypeAnnotationStubs(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<ClassId>) {
|
private fun createTypeAnnotationStubs(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<ClassId>) {
|
||||||
// TODO Calculate type modifiers mask, see 'ModifierMaskUtils.computeMask'
|
val typeModifiers = getTypeModifiersAsWritten(type)
|
||||||
val typeModifiersMask = 0
|
if (annotations.isEmpty() && typeModifiers.isEmpty()) return
|
||||||
if (annotations.isEmpty()) return
|
val typeModifiersMask = ModifierMaskUtils.computeMask { it in typeModifiers }
|
||||||
val modifiersList = KotlinModifierListStubImpl(parent, typeModifiersMask, KtStubElementTypes.MODIFIER_LIST)
|
val modifiersList = KotlinModifierListStubImpl(parent, typeModifiersMask, KtStubElementTypes.MODIFIER_LIST)
|
||||||
createAnnotationStubs(annotations, modifiersList)
|
createAnnotationStubs(annotations, modifiersList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getTypeModifiersAsWritten(type: Type): Set<KtModifierKeywordToken> {
|
||||||
|
val result = hashSetOf<KtModifierKeywordToken>()
|
||||||
|
val classId = c.nameResolver.getClassId(if (type.hasClassName()) type.className else type.typeAliasName)
|
||||||
|
|
||||||
|
if (classId.asSingleFqName().toUnsafe().getFunctionalClassKind() == FunctionClassDescriptor.Kind.SuspendFunction) {
|
||||||
|
result.add(KtTokens.SUSPEND_KEYWORD)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
private fun createTypeArgumentListStub(typeStub: KotlinUserTypeStub, typeArgumentProtoList: List<Type.Argument>) {
|
private fun createTypeArgumentListStub(typeStub: KotlinUserTypeStub, typeArgumentProtoList: List<Type.Argument>) {
|
||||||
if (typeArgumentProtoList.isEmpty()) {
|
if (typeArgumentProtoList.isEmpty()) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
public class TypeModifiers {
|
public class TypeModifiers {
|
||||||
|
val function: () -> Unit = null!!
|
||||||
|
|
||||||
val suspendFunction: suspend () -> Unit = null!!
|
val suspendFunction: suspend () -> Unit = null!!
|
||||||
|
|
||||||
val suspendExtFunction: suspend Any.() -> Unit = null!!
|
val suspendExtFunction: suspend Any.() -> Unit = null!!
|
||||||
|
|||||||
@@ -7,12 +7,23 @@ PsiJetFileStubImpl[package=]
|
|||||||
MODIFIER_LIST[public]
|
MODIFIER_LIST[public]
|
||||||
VALUE_PARAMETER_LIST
|
VALUE_PARAMETER_LIST
|
||||||
CLASS_BODY
|
CLASS_BODY
|
||||||
|
PROPERTY[fqName=TypeModifiers.function, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=function]
|
||||||
|
MODIFIER_LIST[public final]
|
||||||
|
TYPE_REFERENCE
|
||||||
|
FUNCTION_TYPE
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION[referencedName=kotlin]
|
||||||
|
REFERENCE_EXPRESSION[referencedName=Unit]
|
||||||
PROPERTY[fqName=TypeModifiers.functionOnSuspendFunction, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=functionOnSuspendFunction]
|
PROPERTY[fqName=TypeModifiers.functionOnSuspendFunction, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=functionOnSuspendFunction]
|
||||||
MODIFIER_LIST[public final]
|
MODIFIER_LIST[public final]
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
FUNCTION_TYPE
|
FUNCTION_TYPE
|
||||||
FUNCTION_TYPE_RECEIVER
|
FUNCTION_TYPE_RECEIVER
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
|
MODIFIER_LIST[suspend]
|
||||||
FUNCTION_TYPE
|
FUNCTION_TYPE
|
||||||
VALUE_PARAMETER_LIST
|
VALUE_PARAMETER_LIST
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
@@ -29,6 +40,7 @@ PsiJetFileStubImpl[package=]
|
|||||||
PROPERTY[fqName=TypeModifiers.suspendExtFunction, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=suspendExtFunction]
|
PROPERTY[fqName=TypeModifiers.suspendExtFunction, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=suspendExtFunction]
|
||||||
MODIFIER_LIST[public final]
|
MODIFIER_LIST[public final]
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
|
MODIFIER_LIST[suspend]
|
||||||
FUNCTION_TYPE
|
FUNCTION_TYPE
|
||||||
FUNCTION_TYPE_RECEIVER
|
FUNCTION_TYPE_RECEIVER
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
@@ -45,6 +57,7 @@ PsiJetFileStubImpl[package=]
|
|||||||
PROPERTY[fqName=TypeModifiers.suspendFunction, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=suspendFunction]
|
PROPERTY[fqName=TypeModifiers.suspendFunction, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=suspendFunction]
|
||||||
MODIFIER_LIST[public final]
|
MODIFIER_LIST[public final]
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
|
MODIFIER_LIST[suspend]
|
||||||
FUNCTION_TYPE
|
FUNCTION_TYPE
|
||||||
VALUE_PARAMETER_LIST
|
VALUE_PARAMETER_LIST
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
|
|||||||
Reference in New Issue
Block a user