Add support ultra light suspend functions declarations

This commit is contained in:
Igor Yakovlev
2019-06-05 00:54:57 +03:00
parent 16b9c15133
commit fc30e564ba
5 changed files with 63 additions and 10 deletions
@@ -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
}
@@ -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,
@@ -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
@@ -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 }
@@ -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
}