Move refactorings, fix annotations and fix cls-delegate tests

This commit is contained in:
Igor Yakovlev
2019-04-24 18:05:37 +03:00
parent 8e103b6559
commit b485819a30
14 changed files with 449 additions and 388 deletions
@@ -36,7 +36,7 @@ class KtUltraLightNullabilityAnnotation(
override fun getQualifiedName(): String? {
val kotlinType = member.kotlinTypeForNullabilityAnnotation?.takeUnless(KotlinType::isError) ?: return null
val psiType = member.psiTypeForNullabilityAnnotation ?: return null
if (member.isPrivateOrParameterInPrivateMethod() || psiType is PsiPrimitiveType) return null
if (psiType is PsiPrimitiveType) return null
if (kotlinType.isTypeParameter()) {
if (!TypeUtils.hasNullableSuperType(kotlinType)) return NotNull::class.java.name
@@ -53,13 +53,13 @@ class KtUltraLightNullabilityAnnotation(
}
fun DeclarationDescriptor.obtainLightAnnotations(
ultraLightSupport: UltraLightSupport,
ultraLightSupport: KtUltraLightSupport,
parent: PsiElement
): List<KtLightAbstractAnnotation> = annotations.map { KtUltraLightAnnotationForDescriptor(it, ultraLightSupport, parent) }
class KtUltraLightAnnotationForDescriptor(
private val annotationDescriptor: AnnotationDescriptor,
private val ultraLightSupport: UltraLightSupport,
private val ultraLightSupport: KtUltraLightSupport,
parent: PsiElement
) : KtLightAbstractAnnotation(parent, { error("clsDelegate for annotation based on descriptor: $annotationDescriptor") }) {
override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? = null
@@ -100,7 +100,7 @@ class KtUltraLightAnnotationForDescriptor(
private class PsiNameValuePairForAnnotationArgument(
private val _name: String = "",
private val constantValue: ConstantValue<*>,
private val ultraLightSupport: UltraLightSupport,
private val ultraLightSupport: KtUltraLightSupport,
parent: PsiElement
) : KtLightElementBase(parent), PsiNameValuePair {
override val kotlinOrigin: KtElement? get() = null
@@ -121,7 +121,7 @@ private class PsiNameValuePairForAnnotationArgument(
}
private fun ConstantValue<*>.toAnnotationMemberValue(
parent: PsiElement, ultraLightSupport: UltraLightSupport
parent: PsiElement, ultraLightSupport: KtUltraLightSupport
): PsiAnnotationMemberValue? = when (this) {
is AnnotationValue -> KtUltraLightAnnotationForDescriptor(value, ultraLightSupport, parent)
@@ -15,7 +15,6 @@ import com.intellij.psi.impl.light.LightParameterListBuilder
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.backend.common.CodegenUtil
@@ -26,14 +25,12 @@ import org.jetbrains.kotlin.codegen.kotlinType
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.lexer.KtTokens.*
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.containingClass
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DelegationResolver
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -41,7 +38,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
import org.jetbrains.kotlin.resolve.inline.isInlineOnly
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME
@@ -51,7 +47,7 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_N
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val support: UltraLightSupport) :
open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val support: KtUltraLightSupport) :
KtLightClassImpl(classOrObject) {
companion object {
@@ -680,25 +676,11 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
override fun getInitializers(): Array<PsiClassInitializer> = emptyArray()
override fun getContainingClass(): PsiClass? =
if (tooComplex) super.getContainingClass() else classOrObject.containingClass()?.let(KtLightClassForSourceDeclaration::create)
if (tooComplex) super.getContainingClass()
else ((classOrObject.parent as? KtClassBody)?.parent as? KtClassOrObject)?.let(KtLightClassForSourceDeclaration::create)
override fun getParent(): PsiElement? = if (tooComplex) super.getParent() else containingClass ?: containingFile
override fun getScope(): PsiElement? = if (tooComplex) super.getScope() else parent
override fun copy(): KtLightClassImpl = KtUltraLightClass(classOrObject.copy() as KtClassOrObject, support)
}
interface UltraLightSupport {
val moduleName: String
fun findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>?
fun isTooComplexForUltraLightGeneration(element: KtClassOrObject): Boolean
val deprecationResolver: DeprecationResolver
val typeMapper: KotlinTypeMapper
val moduleDescriptor: ModuleDescriptor
}
interface KtUltraLightElementWithNullabilityAnnotation<out T : KtDeclaration, out D : PsiModifierListOwner> : KtLightDeclaration<T, D>,
PsiModifierListOwner {
val kotlinTypeForNullabilityAnnotation: KotlinType?
val psiTypeForNullabilityAnnotation: PsiType?
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import org.jetbrains.kotlin.psi.KtEnumEntry
internal class KtUltraLightClassForEnumEntry(
enumEntry: KtEnumEntry, support: KtUltraLightSupport,
private val enumConstant: PsiEnumConstant
) : KtUltraLightClass(enumEntry, support), PsiEnumConstantInitializer {
private val baseClassReferenceAndType: Pair<PsiJavaCodeReferenceElement, PsiClassType> by lazyPub {
// It should not be null for not-too-complex classes and that is not the case because
// the containing class is not too complex (since we created KtUltraLightClassForEnumEntry instance)
val extendsList =
super.getExtendsList() ?: error("KtUltraLightClass::getExtendsList is null for ${enumEntry.fqName}")
Pair(
extendsList.referenceElements.getOrNull(0) ?: error("No referenceElements found for ${enumEntry.fqName}"),
extendsList.referencedTypes.getOrNull(0) ?: error("No referencedTypes found for ${enumEntry.fqName}")
)
}
override fun getBaseClassType() = baseClassReferenceAndType.second
override fun getBaseClassReference() = baseClassReferenceAndType.first
override fun getArgumentList(): PsiExpressionList? = null
override fun getEnumConstant() = enumConstant
override fun isInQualifiedNew() = false
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiModifierListOwner
import com.intellij.psi.PsiType
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.types.KotlinType
interface KtUltraLightElementWithNullabilityAnnotation<out T : KtDeclaration, out D : PsiModifierListOwner> : KtLightDeclaration<T, D>,
PsiModifierListOwner {
val kotlinTypeForNullabilityAnnotation: KotlinType?
val psiTypeForNullabilityAnnotation: PsiType?
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import org.jetbrains.kotlin.psi.KtEnumEntry
internal class KtUltraLightEnumEntry(
declaration: KtEnumEntry,
name: String,
containingClass: KtUltraLightClass,
support: KtUltraLightSupport,
modifiers: Set<String>
) : KtUltraLightField(declaration, name, containingClass, support, modifiers), PsiEnumConstant {
private val enumEntry get() = declaration as KtEnumEntry
private val _initializingClass by lazyPub {
enumEntry.body?.let { KtUltraLightClassForEnumEntry(enumEntry, containingClass.support, this) }
}
override fun getInitializingClass(): PsiEnumConstantInitializer? = _initializingClass
override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer =
_initializingClass ?: error("cannot create initializing class in light enum constant")
override fun getArgumentList(): PsiExpressionList? = null
override fun resolveMethod(): PsiMethod? = null
override fun resolveConstructor(): PsiMethod? = null
override fun resolveMethodGenerics(): JavaResolveResult = JavaResolveResult.EMPTY
override fun hasInitializer() = true
override fun computeConstantValue(visitedVars: MutableSet<PsiVariable>?) = this
}
@@ -32,10 +32,11 @@ internal open class KtUltraLightField(
protected val declaration: KtNamedDeclaration,
name: String,
private val containingClass: KtUltraLightClass,
private val support: UltraLightSupport,
private val support: KtUltraLightSupport,
modifiers: Set<String>
) : LightFieldBuilder(name, PsiType.NULL, declaration), KtLightField,
KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiField> {
private val modList = object : KtLightSimpleModifierList(this, modifiers) {
override fun hasModifierProperty(name: String): Boolean = when (name) {
PsiModifier.VOLATILE -> hasFieldAnnotation(VOLATILE_ANNOTATION_FQ_NAME)
@@ -53,15 +54,16 @@ internal open class KtUltraLightField(
}
}
override fun isEquivalentTo(another: PsiElement?): Boolean = kotlinOrigin == another
override fun getModifierList(): PsiModifierList = modList
override fun hasModifierProperty(name: String): Boolean =
modifierList.hasModifierProperty(name) //can be removed after IDEA platform does the same
override fun getLanguage(): Language = KotlinLanguage.INSTANCE
private val propertyDescriptor: PropertyDescriptor? by lazyPub {
declaration.resolve() as? PropertyDescriptor
}
private val propertyDescriptor: PropertyDescriptor? by lazyPub { declaration.resolve() as? PropertyDescriptor }
private val kotlinType: KotlinType? by lazyPub {
when {
@@ -109,7 +111,6 @@ internal open class KtUltraLightField(
}
override fun getType(): PsiType = _type
override fun getParent() = containingClass
override fun getContainingClass() = containingClass
override fun getContainingFile(): PsiFile? = containingClass.containingFile
@@ -124,8 +125,10 @@ internal open class KtUltraLightField(
override fun computeConstantValue(visitedVars: MutableSet<PsiVariable>?): Any? = computeConstantValue()
override val kotlinOrigin = declaration
override val clsDelegate: PsiField
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
override val lightMemberOrigin = LightMemberOriginForDeclaration(declaration, JvmDeclarationOriginKind.OTHER)
override fun setName(@NonNls name: String): PsiElement {
@@ -134,63 +137,4 @@ internal open class KtUltraLightField(
}
override fun setInitializer(initializer: PsiExpression?) = cannotModify()
}
internal class KtUltraLightEnumEntry(
declaration: KtEnumEntry,
name: String,
containingClass: KtUltraLightClass,
support: UltraLightSupport,
modifiers: Set<String>
) : KtUltraLightField(declaration, name, containingClass, support, modifiers), PsiEnumConstant {
private val enumEntry get() = declaration as KtEnumEntry
private val _initializingClass by lazyPub {
if (enumEntry.body != null)
KtUltraLightClassForEnumEntry(enumEntry, containingClass.support, this)
else
null
}
override fun getInitializingClass(): PsiEnumConstantInitializer? = _initializingClass
override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer =
_initializingClass ?: error("cannot create initializing class in light enum constant")
override fun getArgumentList(): PsiExpressionList? = null
override fun resolveMethod(): PsiMethod? = null
override fun resolveConstructor(): PsiMethod? = null
override fun resolveMethodGenerics(): JavaResolveResult = JavaResolveResult.EMPTY
override fun hasInitializer() = true
override fun computeConstantValue(visitedVars: MutableSet<PsiVariable>?) = this
}
internal class KtUltraLightClassForEnumEntry(
enumEntry: KtEnumEntry, support: UltraLightSupport,
private val enumConstant: PsiEnumConstant
) : KtUltraLightClass(enumEntry, support), PsiEnumConstantInitializer {
private val baseClassReferenceAndType: Pair<PsiJavaCodeReferenceElement, PsiClassType> by lazyPub {
// It should not be null for not-too-complex classes and that is not the case because
// the containing class is not too complex (since we created KtUltraLightClassForEnumEntry instance)
val extendsList =
super.getExtendsList() ?: error("KtUltraLightClass::getExtendsList is null for ${enumEntry.fqName}")
Pair(
extendsList.referenceElements.getOrNull(0) ?: error("No referenceElements found for ${enumEntry.fqName}"),
extendsList.referencedTypes.getOrNull(0) ?: error("No referencedTypes found for ${enumEntry.fqName}")
)
}
override fun getBaseClassType() = baseClassReferenceAndType.second
override fun getBaseClassReference() = baseClassReferenceAndType.first
override fun getArgumentList(): PsiExpressionList? = null
override fun getEnumConstant() = enumConstant
override fun isInQualifiedNew() = false
}
}
@@ -1,280 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import com.intellij.psi.impl.PsiImplUtil
import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.impl.light.LightTypeParameterListBuilder
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.SearchScope
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
import org.jetbrains.kotlin.asJava.elements.KtLightSimpleModifierList
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.FunctionCodegen
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.types.KotlinType
internal abstract class KtUltraLightMethod(
internal val delegate: LightMethodBuilder,
closestDeclarationForOrigin: KtDeclaration?,
protected val support: UltraLightSupport,
containingClass: KtUltraLightClass
) : KtLightMethodImpl(
{ delegate },
closestDeclarationForOrigin?.let {
LightMemberOriginForDeclaration(it, JvmDeclarationOriginKind.OTHER)
},
containingClass
), KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiMethod> {
override val psiTypeForNullabilityAnnotation: PsiType?
get() = returnType
// These two overrides are necessary because ones from KtLightMethodImpl suppose that clsDelegate.returnTypeElement is valid
// While here we only set return type for LightMethodBuilder (see org.jetbrains.kotlin.asJava.classes.KtUltraLightClass.asJavaMethod)
override fun getReturnTypeElement(): PsiTypeElement? = null
override fun getReturnType(): PsiType? = clsDelegate.returnType
override fun buildParametersForList(): List<PsiParameter> = clsDelegate.parameterList.parameters.toList()
// should be in super
override fun isVarArgs() = PsiImplUtil.isVarArgs(this)
abstract override fun buildTypeParameterList(): PsiTypeParameterList
private val _throwsList: PsiReferenceList by lazyPub {
val list =
object : KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST) {
override fun getParent() = this@KtUltraLightMethod
override fun getContainingFile() = this@KtUltraLightMethod.containingFile
}
computeDescriptor()?.let {
for (ex in FunctionCodegen.getThrownExceptions(it)) {
val psiClassType = ex.defaultType.asPsiType(support, TypeMappingMode.DEFAULT, list) as? PsiClassType ?: continue
list.addReference(psiClassType)
}
}
list
}
override fun getHierarchicalMethodSignature() = PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this)
override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean): List<MethodSignatureBackedByPsiMethod> =
PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess)
override fun findDeepestSuperMethod() = PsiSuperMethodImplUtil.findDeepestSuperMethod(this)
override fun findDeepestSuperMethods(): Array<out PsiMethod> = PsiSuperMethodImplUtil.findDeepestSuperMethods(this)
override fun findSuperMethods(): Array<out PsiMethod> = PsiSuperMethodImplUtil.findSuperMethods(this)
override fun findSuperMethods(checkAccess: Boolean): Array<out PsiMethod> =
PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess)
override fun findSuperMethods(parentClass: PsiClass?): Array<out PsiMethod> =
PsiSuperMethodImplUtil.findSuperMethods(this, parentClass)
override fun getThrowsList(): PsiReferenceList = _throwsList
abstract fun computeDescriptor(): FunctionDescriptor?
}
internal class KtUltraLightMethodForSourceDeclaration(
delegate: LightMethodBuilder,
declaration: KtDeclaration,
support: UltraLightSupport,
containingClass: KtUltraLightClass
) : KtUltraLightMethod(
delegate,
declaration,
support, containingClass
) {
override val kotlinTypeForNullabilityAnnotation: KotlinType?
get() = kotlinOrigin?.getKotlinType()
override fun buildTypeParameterList(): PsiTypeParameterList {
val origin = kotlinOrigin
return if (origin is KtFunction || origin is KtProperty)
buildTypeParameterList(origin as KtTypeParameterListOwner, this, support)
else LightTypeParameterListBuilder(manager, language)
}
override fun computeDescriptor() = kotlinOrigin?.resolve() as? FunctionDescriptor
}
internal class KtUltraLightMethodForDescriptor(
private val descriptor: FunctionDescriptor,
delegate: LightMethodBuilder,
closestDeclarationForOrigin: KtDeclaration?,
support: UltraLightSupport,
containingClass: KtUltraLightClass
) : KtUltraLightMethod(
delegate,
closestDeclarationForOrigin,
support,
containingClass
) {
override fun buildTypeParameterList() = buildTypeParameterList(descriptor, this, support)
override fun computeDescriptor() = descriptor
override val kotlinTypeForNullabilityAnnotation: KotlinType?
get() = descriptor.returnType
override val givenAnnotations: List<KtLightAbstractAnnotation>
get() = descriptor.obtainLightAnnotations(support, this)
}
internal abstract class KtUltraLightParameter(
name: String,
override val kotlinOrigin: KtDeclaration?,
protected val support: UltraLightSupport,
method: KtLightMethod
) : org.jetbrains.kotlin.asJava.elements.LightParameter(
name,
PsiType.NULL,
method,
method.language
), KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiParameter> {
override val clsDelegate: PsiParameter
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) }
override fun getModifierList(): PsiModifierList = lightModifierList
override fun getNavigationElement(): PsiElement = kotlinOrigin ?: method.navigationElement
override fun getUseScope(): SearchScope = kotlinOrigin?.useScope ?: LocalSearchScope(this)
override fun isValid() = parent.isValid
protected abstract val kotlinType: KotlinType?
protected abstract fun computeContainingDescriptor(): CallableDescriptor?
override val kotlinTypeForNullabilityAnnotation: KotlinType?
get() {
val type = kotlinType
return if (isVarArgs && type != null && KotlinBuiltIns.isArray(type)) {
type.arguments[0].type
} else {
type
}
}
override val psiTypeForNullabilityAnnotation: PsiType?
get() = type
private val _type: PsiType by lazyPub {
val kotlinType = kotlinType ?: return@lazyPub PsiType.NULL
val containingDescriptor = computeContainingDescriptor() ?: return@lazyPub PsiType.NULL
support.mapType(this) { typeMapper, sw ->
typeMapper.writeParameterType(sw, kotlinType, containingDescriptor)
}
}
override fun getType(): PsiType = _type
override fun getContainingFile(): PsiFile = method.containingFile
override fun getParent(): PsiElement = method.parameterList
override fun equals(other: Any?): Boolean =
other is KtUltraLightParameter && other.kotlinOrigin == this.kotlinOrigin
override fun hashCode(): Int = kotlinOrigin.hashCode()
abstract override fun isVarArgs(): Boolean
}
internal abstract class KtAbstractUltraLightParameterForDeclaration(
name: String,
kotlinOrigin: KtDeclaration?,
support: UltraLightSupport,
method: KtLightMethod,
protected val containingDeclaration: KtCallableDeclaration
) : KtUltraLightParameter(name, kotlinOrigin, support, method) {
override fun computeContainingDescriptor() = containingDeclaration.resolve() as? CallableMemberDescriptor
}
internal class KtUltraLightParameterForSource(
name: String,
override val kotlinOrigin: KtParameter,
support: UltraLightSupport,
method: KtLightMethod,
containingDeclaration: KtCallableDeclaration
) : KtAbstractUltraLightParameterForDeclaration(name, kotlinOrigin, support, method, containingDeclaration) {
override val kotlinType: KotlinType? by lazyPub {
kotlinOrigin.getKotlinType()
}
override fun isVarArgs(): Boolean = kotlinOrigin.isVarArg && method.parameterList.parameters.last() == this
override fun setName(@NonNls name: String): PsiElement {
kotlinOrigin.setName(name)
return this
}
}
internal class KtUltraLightParameterForSetterParameter(
name: String,
// KtProperty or KtParameter from primary constructor
private val property: KtDeclaration,
support: UltraLightSupport,
method: KtLightMethod,
containingDeclaration: KtCallableDeclaration
) : KtAbstractUltraLightParameterForDeclaration(name, null, support, method, containingDeclaration) {
override val kotlinType: KotlinType? by lazyPub {
property.getKotlinType()
}
override fun isVarArgs(): Boolean = false
}
internal class KtUltraLightReceiverParameter(
containingDeclaration: KtCallableDeclaration,
support: UltraLightSupport,
method: KtLightMethod
) : KtAbstractUltraLightParameterForDeclaration("\$self", null, support, method, containingDeclaration) {
override fun isVarArgs(): Boolean = false
override val kotlinType: KotlinType? by lazyPub {
computeContainingDescriptor()?.extensionReceiverParameter?.type
}
}
internal class KtUltraLightParameterForDescriptor(
private val descriptor: ParameterDescriptor,
kotlinOrigin: KtDeclaration?,
support: UltraLightSupport,
method: KtLightMethod
) : KtUltraLightParameter(
if (descriptor.name.isSpecial) "\$self" else descriptor.name.identifier,
kotlinOrigin, support, method
) {
override val kotlinType: KotlinType?
get() = descriptor.type
override fun computeContainingDescriptor() = descriptor.containingDeclaration as? CallableMemberDescriptor
override fun isVarArgs() = (descriptor as? ValueParameterDescriptor)?.varargElementType != null
override val givenAnnotations: List<KtLightAbstractAnnotation>
get() = descriptor.obtainLightAnnotations(support, this)
}
@@ -0,0 +1,137 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import com.intellij.psi.impl.PsiImplUtil
import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.impl.light.LightTypeParameterListBuilder
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
import org.jetbrains.kotlin.codegen.FunctionCodegen
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.types.KotlinType
internal abstract class KtUltraLightMethod(
internal val delegate: LightMethodBuilder,
closestDeclarationForOrigin: KtDeclaration?,
protected val support: KtUltraLightSupport,
containingClass: KtUltraLightClass
) : KtLightMethodImpl(
{ delegate },
closestDeclarationForOrigin?.let {
LightMemberOriginForDeclaration(it, JvmDeclarationOriginKind.OTHER)
},
containingClass
), KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiMethod> {
override val psiTypeForNullabilityAnnotation: PsiType?
get() = returnType
// These two overrides are necessary because ones from KtLightMethodImpl suppose that clsDelegate.returnTypeElement is valid
// While here we only set return type for LightMethodBuilder (see org.jetbrains.kotlin.asJava.classes.KtUltraLightClass.asJavaMethod)
override fun getReturnTypeElement(): PsiTypeElement? = null
override fun getReturnType(): PsiType? = clsDelegate.returnType
override fun buildParametersForList(): List<PsiParameter> = clsDelegate.parameterList.parameters.toList()
// should be in super
override fun isVarArgs() = PsiImplUtil.isVarArgs(this)
abstract override fun buildTypeParameterList(): PsiTypeParameterList
private val _throwsList: PsiReferenceList by lazyPub {
val list =
object : KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST) {
override fun getParent() = this@KtUltraLightMethod
override fun getContainingFile() = this@KtUltraLightMethod.containingFile
}
computeDescriptor()?.let {
for (ex in FunctionCodegen.getThrownExceptions(it)) {
val psiClassType = ex.defaultType.asPsiType(support, TypeMappingMode.DEFAULT, list) as? PsiClassType ?: continue
list.addReference(psiClassType)
}
}
list
}
override fun getHierarchicalMethodSignature() = PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this)
override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean): List<MethodSignatureBackedByPsiMethod> =
PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess)
override fun findDeepestSuperMethod() = PsiSuperMethodImplUtil.findDeepestSuperMethod(this)
override fun findDeepestSuperMethods(): Array<out PsiMethod> = PsiSuperMethodImplUtil.findDeepestSuperMethods(this)
override fun findSuperMethods(): Array<out PsiMethod> = PsiSuperMethodImplUtil.findSuperMethods(this)
override fun findSuperMethods(checkAccess: Boolean): Array<out PsiMethod> =
PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess)
override fun findSuperMethods(parentClass: PsiClass?): Array<out PsiMethod> =
PsiSuperMethodImplUtil.findSuperMethods(this, parentClass)
override fun getThrowsList(): PsiReferenceList = _throwsList
abstract fun computeDescriptor(): FunctionDescriptor?
}
internal class KtUltraLightMethodForSourceDeclaration(
delegate: LightMethodBuilder,
declaration: KtDeclaration,
support: KtUltraLightSupport,
containingClass: KtUltraLightClass
) : KtUltraLightMethod(
delegate,
declaration,
support, containingClass
) {
override val kotlinTypeForNullabilityAnnotation: KotlinType?
get() = kotlinOrigin?.getKotlinType()
override fun buildTypeParameterList(): PsiTypeParameterList {
val origin = kotlinOrigin
return if (origin is KtFunction || origin is KtProperty)
buildTypeParameterList(origin as KtTypeParameterListOwner, this, support)
else LightTypeParameterListBuilder(manager, language)
}
override fun computeDescriptor() = kotlinOrigin?.resolve() as? FunctionDescriptor
}
internal class KtUltraLightMethodForDescriptor(
private val descriptor: FunctionDescriptor,
delegate: LightMethodBuilder,
closestDeclarationForOrigin: KtDeclaration?,
support: KtUltraLightSupport,
containingClass: KtUltraLightClass
) : KtUltraLightMethod(
delegate,
closestDeclarationForOrigin,
support,
containingClass
) {
override fun buildTypeParameterList() = buildTypeParameterList(descriptor, this, support)
override fun computeDescriptor() = descriptor
override val kotlinTypeForNullabilityAnnotation: KotlinType?
get() = descriptor.returnType
override val givenAnnotations: List<KtLightAbstractAnnotation>
get() = descriptor.obtainLightAnnotations(support, this)
}
@@ -0,0 +1,162 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.SearchScope
import org.jetbrains.annotations.NonNls
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
internal abstract class KtUltraLightParameter(
name: String,
override val kotlinOrigin: KtDeclaration?,
protected val support: KtUltraLightSupport,
method: KtLightMethod
) : org.jetbrains.kotlin.asJava.elements.LightParameter(
name,
PsiType.NULL,
method,
method.language
), KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiParameter> {
override fun isEquivalentTo(another: PsiElement?): Boolean = kotlinOrigin == another
override val clsDelegate: PsiParameter
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) }
override fun getModifierList(): PsiModifierList = lightModifierList
override fun getNavigationElement(): PsiElement = kotlinOrigin ?: method.navigationElement
override fun getUseScope(): SearchScope = kotlinOrigin?.useScope ?: LocalSearchScope(this)
override fun isValid() = parent.isValid
protected abstract val kotlinType: KotlinType?
protected abstract fun computeContainingDescriptor(): CallableDescriptor?
override val kotlinTypeForNullabilityAnnotation: KotlinType?
get() {
val type = kotlinType
return if (isVarArgs && type != null && KotlinBuiltIns.isArray(type)) {
type.arguments[0].type
} else {
type
}
}
override val psiTypeForNullabilityAnnotation: PsiType?
get() = type
private val _type: PsiType by lazyPub {
val kotlinType = kotlinType ?: return@lazyPub PsiType.NULL
val containingDescriptor = computeContainingDescriptor() ?: return@lazyPub PsiType.NULL
support.mapType(this) { typeMapper, sw ->
typeMapper.writeParameterType(sw, kotlinType, containingDescriptor)
}
}
override fun getType(): PsiType = _type
override fun getContainingFile(): PsiFile = method.containingFile
override fun getParent(): PsiElement = method.parameterList
override fun equals(other: Any?): Boolean =
other is KtUltraLightParameter && other.kotlinOrigin == this.kotlinOrigin
override fun hashCode(): Int = kotlinOrigin.hashCode()
abstract override fun isVarArgs(): Boolean
}
internal abstract class KtAbstractUltraLightParameterForDeclaration(
name: String,
kotlinOrigin: KtDeclaration?,
support: KtUltraLightSupport,
method: KtLightMethod,
protected val containingDeclaration: KtCallableDeclaration
) : KtUltraLightParameter(name, kotlinOrigin, support, method) {
override fun computeContainingDescriptor() = containingDeclaration.resolve() as? CallableMemberDescriptor
}
internal class KtUltraLightParameterForSource(
name: String,
override val kotlinOrigin: KtParameter,
support: KtUltraLightSupport,
method: KtLightMethod,
containingDeclaration: KtCallableDeclaration
) : KtAbstractUltraLightParameterForDeclaration(name, kotlinOrigin, support, method, containingDeclaration) {
override val kotlinType: KotlinType? by lazyPub {
kotlinOrigin.getKotlinType()
}
override fun isVarArgs(): Boolean = kotlinOrigin.isVarArg && method.parameterList.parameters.last() == this
override fun setName(@NonNls name: String): PsiElement {
kotlinOrigin.setName(name)
return this
}
}
internal class KtUltraLightParameterForSetterParameter(
name: String,
// KtProperty or KtParameter from primary constructor
private val property: KtDeclaration,
support: KtUltraLightSupport,
method: KtLightMethod,
containingDeclaration: KtCallableDeclaration
) : KtAbstractUltraLightParameterForDeclaration(name, null, support, method, containingDeclaration) {
override val kotlinType: KotlinType? by lazyPub { property.getKotlinType() }
override fun isVarArgs(): Boolean = false
}
internal class KtUltraLightReceiverParameter(
containingDeclaration: KtCallableDeclaration,
support: KtUltraLightSupport,
method: KtLightMethod
) : KtAbstractUltraLightParameterForDeclaration("\$self", null, support, method, containingDeclaration) {
override fun isVarArgs(): Boolean = false
override val kotlinType: KotlinType? by lazyPub { computeContainingDescriptor()?.extensionReceiverParameter?.type }
}
internal class KtUltraLightParameterForDescriptor(
private val descriptor: ParameterDescriptor,
kotlinOrigin: KtDeclaration?,
support: KtUltraLightSupport,
method: KtLightMethod
) : KtUltraLightParameter(
if (descriptor.name.isSpecial) "\$self" else descriptor.name.identifier,
kotlinOrigin, support, method
) {
override val kotlinType: KotlinType?
get() = descriptor.type
override fun computeContainingDescriptor() = descriptor.containingDeclaration as? CallableMemberDescriptor
override fun isVarArgs() = (descriptor as? ValueParameterDescriptor)?.varargElementType != null
override val givenAnnotations: List<KtLightAbstractAnnotation>
get() = descriptor.obtainLightAnnotations(support, this)
}
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
interface KtUltraLightSupport {
val moduleName: String
fun findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>?
fun isTooComplexForUltraLightGeneration(element: KtClassOrObject): Boolean
val deprecationResolver: DeprecationResolver
val typeMapper: KotlinTypeMapper
val moduleDescriptor: ModuleDescriptor
}
@@ -12,12 +12,10 @@ import com.intellij.psi.impl.compiled.ClsTypeElementImpl
import com.intellij.psi.impl.compiled.SignatureParsing
import com.intellij.psi.impl.compiled.StubBuildingVisitor
import com.intellij.psi.impl.light.*
import com.intellij.psi.search.SearchScope
import com.intellij.util.BitUtil.isSet
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterListBuilder
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
@@ -40,7 +38,7 @@ import java.text.StringCharacterIterator
internal fun buildTypeParameterList(
declaration: CallableMemberDescriptor,
owner: PsiTypeParameterListOwner,
support: UltraLightSupport
support: KtUltraLightSupport
): PsiTypeParameterList = buildTypeParameterList(
declaration, owner, support,
object : TypeParametersSupport<CallableMemberDescriptor, TypeParameterDescriptor> {
@@ -60,7 +58,7 @@ internal fun buildTypeParameterList(
internal fun buildTypeParameterList(
declaration: KtTypeParameterListOwner,
owner: PsiTypeParameterListOwner,
support: UltraLightSupport
support: KtUltraLightSupport
): PsiTypeParameterList = buildTypeParameterList(
declaration, owner, support,
object : TypeParametersSupport<KtTypeParameterListOwner, KtTypeParameter> {
@@ -86,7 +84,7 @@ interface TypeParametersSupport<D, T> {
internal fun <D, T> buildTypeParameterList(
declaration: D,
owner: PsiTypeParameterListOwner,
support: UltraLightSupport,
support: KtUltraLightSupport,
typeParametersSupport: TypeParametersSupport<D, T>
): PsiTypeParameterList {
@@ -132,14 +130,14 @@ internal fun KtElement.analyze() = LightClassGenerationSupport.getInstance(proje
// copy-pasted from kotlinInternalUastUtils.kt and post-processed
internal fun KotlinType.asPsiType(
support: UltraLightSupport,
support: KtUltraLightSupport,
mode: TypeMappingMode,
psiContext: PsiElement
): PsiType = support.mapType(psiContext) { typeMapper, signatureWriter ->
typeMapper.mapType(this, signatureWriter, mode)
}
internal fun UltraLightSupport.mapType(
internal fun KtUltraLightSupport.mapType(
psiContext: PsiElement,
mapTypeToSignatureWriter: (KotlinTypeMapper, JvmSignatureWriter) -> Unit
): PsiType {
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.codegen.ClassBuilderMode
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
@@ -72,7 +71,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
}
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return null
return KtUltraLightClass(element, object : UltraLightSupport {
return KtUltraLightClass(element, object : KtUltraLightSupport {
override fun isTooComplexForUltraLightGeneration(element: KtClassOrObject): Boolean {
val facet = KotlinFacet.get(module)
val pluginClasspath = facet?.configuration?.settings?.compilerArguments?.pluginClasspaths
@@ -12,6 +12,7 @@ import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.asJava.LightClassUtil;
import org.jetbrains.kotlin.asJava.classes.KtLightClass;
import org.jetbrains.kotlin.asJava.classes.KtUltraLightClass;
import org.jetbrains.kotlin.asJava.elements.KtLightMethod;
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase;
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor;
@@ -294,9 +295,11 @@ public class KotlinJavaFacadeTest extends KotlinLightCodeInsightFixtureTestCase
assertNotNull(String.format("Failed to wrap jetClass '%s' to class", ktClass.getText()), lightClass);
// This invokes codegen with ClassBuilderMode = LIGHT_CLASSES
// No exception/error should happen here
lightClass.getClsDelegate();
if (!(lightClass instanceof KtUltraLightClass)){
// This invokes codegen with ClassBuilderMode = LIGHT_CLASSES
// No exception/error should happen here
lightClass.getClsDelegate();
}
}
@NotNull
@@ -283,8 +283,8 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
)
TestCase.assertEquals(
"KtLightMethodImpl -> org.jetbrains.annotations.NotNull," +
" KtLightFieldForDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
" KtUltraLightField -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
)
}
@@ -335,14 +335,14 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
)
TestCase.assertEquals(
"KtLightMethodImpl -> org.jetbrains.annotations.NotNull," +
" KtLightFieldForDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
" KtUltraLightField -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
)
}
private fun annotationsString(findElementByText: KtModifierListOwner) = findElementByText.toLightElements()
.joinToString { elem -> "${elem.javaClass.simpleName} -> ${(elem as PsiModifierListOwner).annotations.joinToString { it.qualifiedName!! }}" }
.joinToString { elem -> "${elem.javaClass.simpleName} -> ${(elem as PsiModifierListOwner).annotations.mapNotNull { it.qualifiedName }.joinToString()}" }
fun testDontMakePublicPublic() {
myFixture.configureByText(