From fc30e564baa8249f682d5ecfeb4ac1d88d69caef Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Wed, 5 Jun 2019 00:54:57 +0300 Subject: [PATCH] Add support ultra light suspend functions declarations --- .../classes/ultraLightMembersCreator.kt | 23 +++++++++-- .../asJava/classes/ultraLightParameters.kt | 41 +++++++++++++++++-- .../asJava/classes/ultraLightSupport.kt | 1 + .../jetbrains/kotlin/psi/psiUtil/psiUtils.kt | 1 + .../resolve/IDELightClassGenerationSupport.kt | 7 +++- 5 files changed, 63 insertions(+), 10 deletions(-) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt index 800e78d8781..ee6783faaab 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt @@ -19,12 +19,15 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens.REIFIED_KEYWORD import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi +import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.inline.isInlineOnly import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME @@ -144,7 +147,6 @@ internal class UltraLightMembersCreator( val wrapper = KtUltraLightMethodForSourceDeclaration(method, ktFunction, support, containingClass) addReceiverParameter(ktFunction, wrapper) - var remainingNumberOfDefaultParametersToAdd = if (numberOfDefaultParametersToAdd >= 0) numberOfDefaultParametersToAdd @@ -160,10 +162,23 @@ internal class UltraLightMembersCreator( method.addParameter(KtUltraLightParameterForSource(parameter.name.orEmpty(), parameter, support, wrapper, ktFunction)) } - val returnType: PsiType? by lazyPub { - if (isConstructor) null - else methodReturnType(ktFunction, wrapper) + + val isSuspendFunction = ktFunction.modifierList?.hasSuspendModifier() == true + if (isSuspendFunction) { + method.addParameter(KtUltraLightSuspendContinuationParameter(ktFunction, support, wrapper)) } + + val returnType: PsiType? by lazyPub { + when { + isConstructor -> null + isSuspendFunction -> support.moduleDescriptor + .builtIns + .nullableAnyType + .asPsiType(support, TypeMappingMode.DEFAULT, wrapper) + else -> methodReturnType(ktFunction, wrapper) + } + } + method.setMethodReturnType { returnType } return wrapper } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightParameters.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightParameters.kt index 7672b333345..becb0e43ad9 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightParameters.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightParameters.kt @@ -13,14 +13,47 @@ import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.elements.KtLightSimpleModifierList import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.ParameterDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_FUNCTION_CONTINUATION_PARAMETER +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.load.kotlin.TypeMappingMode +import org.jetbrains.kotlin.psi.KtFunction + +internal class KtUltraLightSuspendContinuationParameter( + private val ktFunction: KtFunction, + support: KtUltraLightSupport, + method: KtLightMethod +) : org.jetbrains.kotlin.asJava.elements.LightParameter(SUSPEND_FUNCTION_CONTINUATION_PARAMETER, PsiType.NULL, method, method.language) { + + private val psiType by lazyPub { + val descriptor = ktFunction.resolve() as? FunctionDescriptor + val returnType = descriptor?.returnType ?: return@lazyPub PsiType.NULL + val typeFromDescriptor = support.moduleDescriptor.getContinuationOfTypeOrAny(returnType, support.isReleasedCoroutine) + typeFromDescriptor.asPsiType(support, TypeMappingMode.DEFAULT, method) + } + + private val lightModifierList by lazyPub { KtLightSimpleModifierList(method, emptySet()) } + + override fun getType(): PsiType = psiType + + override fun equals(other: Any?): Boolean = + other is KtUltraLightSuspendContinuationParameter && other.ktFunction === this.ktFunction + + override fun isVarArgs(): Boolean = false + override fun hashCode(): Int = name.hashCode() + override fun getModifierList(): PsiModifierList = lightModifierList + override fun getNavigationElement(): PsiElement = ktFunction.navigationElement + override fun getUseScope(): SearchScope = ktFunction.useScope + override fun isValid() = ktFunction.isValid + override fun getContainingFile(): PsiFile = ktFunction.containingFile + override fun getParent(): PsiElement = method.parameterList + + override fun isEquivalentTo(another: PsiElement?): Boolean = + another is KtUltraLightSuspendContinuationParameter && another.psiType == this.psiType +} internal abstract class KtUltraLightParameter( name: String, diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightSupport.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightSupport.kt index 68e76ee1d11..6d6fa83c7a6 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightSupport.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightSupport.kt @@ -22,6 +22,7 @@ interface KtUltraLightSupport { val deprecationResolver: DeprecationResolver val typeMapper: KotlinTypeMapper val moduleDescriptor: ModuleDescriptor + val isReleasedCoroutine: Boolean companion object { // This property may be removed once IntelliJ versions earlier than 2018.3 become unsupported diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/psiUtil/psiUtils.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/psiUtil/psiUtils.kt index 804f86e3f08..03308f75970 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/psiUtil/psiUtils.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/psiUtil/psiUtils.kt @@ -443,6 +443,7 @@ fun KtModifierList.hasExpectModifier() = hasModifier(KtTokens.HEADER_KEYWORD) || fun KtModifierListOwner.hasActualModifier() = hasModifier(KtTokens.IMPL_KEYWORD) || hasModifier(KtTokens.ACTUAL_KEYWORD) fun KtModifierList.hasActualModifier() = hasModifier(KtTokens.IMPL_KEYWORD) || hasModifier(KtTokens.ACTUAL_KEYWORD) +fun KtModifierList.hasSuspendModifier() = hasModifier(KtTokens.SUSPEND_KEYWORD) fun ASTNode.children() = generateSequence(firstChildNode) { node -> node.treeNext } fun ASTNode.parents() = generateSequence(treeParent) { node -> node.treeParent } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index 3d5daea9aa2..4a4738f63ae 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -73,6 +73,10 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG else -> this.text } + override val isReleasedCoroutine + get() = KotlinFacet.get(module) + ?.configuration?.settings?.languageLevel?.let { it.major >= 1 && it.minor >= 3 } ?: true + override fun isTooComplexForUltraLightGeneration(element: KtDeclaration): Boolean { val facet = KotlinFacet.get(module) val pluginClasspaths = facet?.configuration?.settings?.compilerArguments?.pluginClasspaths @@ -145,8 +149,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG private fun findTooComplexDeclaration(declaration: KtDeclaration): PsiElement? { if (declaration.hasExpectModifier() || declaration.hasModifier(KtTokens.ANNOTATION_KEYWORD) || - declaration.hasModifier(KtTokens.INLINE_KEYWORD) && declaration is KtClassOrObject || - declaration.hasModifier(KtTokens.SUSPEND_KEYWORD) + declaration.hasModifier(KtTokens.INLINE_KEYWORD) && declaration is KtClassOrObject ) { return declaration }