Minor. Split ultraLightPsi.kt into three files

By one for PsiClass, PsiField and PsiMethod implementations
This commit is contained in:
Denis Zharkov
2018-11-23 16:02:31 +03:00
parent 5231da4320
commit 5cf2d659dc
3 changed files with 310 additions and 255 deletions
@@ -0,0 +1,147 @@
/*
* Copyright 2010-2018 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.lang.Language
import com.intellij.psi.*
import com.intellij.psi.impl.light.LightFieldBuilder
import com.intellij.psi.util.TypeConversionUtil
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightSimpleModifierList
import org.jetbrains.kotlin.codegen.PropertyCodegen
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.resolve.jvm.annotations.TRANSIENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
internal open class KtUltraLightField(
private val declaration: KtNamedDeclaration,
name: String,
private val containingClass: KtUltraLightClass,
private val support: UltraLightSupport,
modifiers: Set<String>
) : LightFieldBuilder(name, PsiType.NULL, declaration), KtLightField {
private val modList = object : KtLightSimpleModifierList(this, modifiers) {
override fun hasModifierProperty(name: String): Boolean = when (name) {
PsiModifier.VOLATILE -> hasFieldAnnotation(VOLATILE_ANNOTATION_FQ_NAME)
PsiModifier.TRANSIENT -> hasFieldAnnotation(TRANSIENT_ANNOTATION_FQ_NAME)
else -> super.hasModifierProperty(name)
}
private fun hasFieldAnnotation(fqName: FqName): Boolean {
val annotation = support.findAnnotation(declaration, fqName)?.first ?: return false
val target = annotation.useSiteTarget?.getAnnotationUseSiteTarget() ?: return true
val expectedTarget =
if (declaration is KtProperty && declaration.hasDelegate()) AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
else AnnotationUseSiteTarget.FIELD
return target == expectedTarget
}
}
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 _type: PsiType by lazyPub {
fun nonExistent() = JavaPsiFacade.getElementFactory(project).createTypeFromText("error.NonExistentClass", declaration)
val propertyDescriptor: PropertyDescriptor? by lazyPub {
declaration.resolve() as? PropertyDescriptor
}
when {
declaration is KtProperty && declaration.hasDelegate() ->
propertyDescriptor
?.let {
val context = LightClassGenerationSupport.getInstance(project).analyze(declaration)
PropertyCodegen.getDelegateTypeForProperty(declaration, it, context)
}
?.let { it.asPsiType(support, TypeMappingMode.getOptimalModeForValueParameter(it), this) }
?.let(TypeConversionUtil::erasure)
?: nonExistent()
declaration is KtObjectDeclaration ->
KtLightClassForSourceDeclaration.create(declaration)?.let { JavaPsiFacade.getElementFactory(project).createType(it) }
?: nonExistent()
declaration is KtEnumEntry -> {
(containingClass.kotlinOrigin.resolve() as? ClassDescriptor)
?.defaultType?.asPsiType(support, TypeMappingMode.DEFAULT, this)
?: nonExistent()
}
else -> {
val kotlinType = declaration.getKotlinType() ?: return@lazyPub PsiType.NULL
val descriptor = propertyDescriptor ?: return@lazyPub PsiType.NULL
support.mapType(this) { typeMapper, sw ->
typeMapper.writeFieldSignature(kotlinType, descriptor, sw)
}
}
}
}
override fun getType(): PsiType = _type
override fun getParent() = containingClass
override fun getContainingClass() = containingClass
override fun getContainingFile(): PsiFile? = containingClass.containingFile
override fun computeConstantValue(): Any? =
if (hasModifierProperty(PsiModifier.FINAL) &&
(TypeConversionUtil.isPrimitiveAndNotNull(_type) || _type.equalsToText(CommonClassNames.JAVA_LANG_STRING))
)
(declaration.resolve() as? VariableDescriptor)?.compileTimeInitializer?.value
else null
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 {
(kotlinOrigin as? KtNamedDeclaration)?.setName(name)
return this
}
override fun setInitializer(initializer: PsiExpression?) = cannotModify()
}
internal class KtUltraLightEnumEntry(
declaration: KtNamedDeclaration,
name: String,
containingClass: KtUltraLightClass,
support: UltraLightSupport,
modifiers: Set<String>
) : KtUltraLightField(declaration, name, containingClass, support, modifiers), PsiEnumConstant {
override fun getInitializingClass(): PsiEnumConstantInitializer? = null
override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer =
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
}
@@ -0,0 +1,154 @@
/*
* Copyright 2010-2018 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 org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
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.codegen.FunctionCodegen
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.types.KotlinType
internal class KtUltraLightMethod(
internal val delegate: LightMethodBuilder,
originalElement: KtDeclaration,
private val support: UltraLightSupport,
containingClass: KtUltraLightClass
) : KtLightMethodImpl({ delegate }, LightMemberOriginForDeclaration(originalElement, JvmDeclarationOriginKind.OTHER), containingClass) {
// 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)
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)
}
private val _throwsList: PsiReferenceList by lazyPub {
val list = KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST)
(kotlinOrigin?.resolve() as? FunctionDescriptor)?.let {
for (ex in FunctionCodegen.getThrownExceptions(it)) {
list.addReference(ex.fqNameSafe.asString())
}
}
list
}
override fun getHierarchicalMethodSignature() = PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this)
override fun getThrowsList(): PsiReferenceList = _throwsList
}
internal class KtUltraLightParameter(
name: String,
override val kotlinOrigin: KtDeclaration,
private val support: UltraLightSupport,
method: KtLightMethod,
private val receiver: KtTypeReference?,
private val containingFunction: KtCallableDeclaration
) : org.jetbrains.kotlin.asJava.elements.LightParameter(
name,
PsiType.NULL,
method,
method.language
),
KtLightDeclaration<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 isVarArgs(): Boolean =
kotlinOrigin is KtParameter && kotlinOrigin.isVarArg && method.parameterList.parameters.last() == this
override fun getModifierList(): PsiModifierList = lightModifierList
override fun getNavigationElement(): PsiElement = kotlinOrigin
override fun isValid() = parent.isValid
private val kotlinType: KotlinType? by lazyPub {
when {
receiver != null -> (kotlinOrigin.resolve() as? CallableMemberDescriptor)?.extensionReceiverParameter?.type
else -> kotlinOrigin.getKotlinType()
}
}
private val _type: PsiType by lazyPub {
val kotlinType = kotlinType ?: return@lazyPub PsiType.NULL
val containingDescriptor = containingFunction.resolve() as? CallableDescriptor ?: return@lazyPub PsiType.NULL
support.mapType(this) { typeMapper, sw ->
typeMapper.writeParameterType(sw, kotlinType, containingDescriptor)
}
}
override fun getType(): PsiType = _type
override fun setName(@NonNls name: String): PsiElement {
(kotlinOrigin as? KtVariableDeclaration)?.setName(name)
return this
}
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()
internal fun annotatedOrigin(): KtAnnotated? {
if (receiver != null) return receiver
if (kotlinOrigin is KtProperty) {
return null // we're a setter of a property with no explicit declaration, so we don't have annotation
}
return kotlinOrigin
}
internal fun getTypeForNullability(): KotlinType? {
if (receiver != null) return kotlinType
if (kotlinOrigin is KtProperty) {
if (kotlinOrigin.setter?.hasModifier(KtTokens.PRIVATE_KEYWORD) == true) return null
return kotlinType
}
if (kotlinOrigin is KtParameter) {
val reference = kotlinOrigin.typeReference
if (kotlinOrigin.isVarArg && reference != null) {
LightClassGenerationSupport.getInstance(project).analyze(reference)[BindingContext.TYPE, reference]?.let { return it }
}
if (reference != null || kotlinOrigin.parent?.parent is KtPropertyAccessor) {
return kotlinType
}
}
return null
}
}
@@ -6,29 +6,23 @@
package org.jetbrains.kotlin.asJava.classes
import com.google.common.annotations.VisibleForTesting
import com.intellij.lang.Language
import com.intellij.psi.*
import com.intellij.psi.impl.PsiClassImplUtil
import com.intellij.psi.impl.PsiImplUtil
import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.light.*
import com.intellij.psi.util.TypeConversionUtil
import org.jetbrains.annotations.NonNls
import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.impl.light.LightModifierList
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.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.FunctionCodegen
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.PropertyCodegen
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.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
@@ -41,11 +35,12 @@ 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.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
import org.jetbrains.kotlin.resolve.inline.isInlineOnly
import org.jetbrains.kotlin.resolve.jvm.annotations.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.STRICTFP_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
@@ -594,247 +589,6 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
override fun copy(): KtLightClassImpl = KtUltraLightClass(classOrObject.copy() as KtClassOrObject, support)
}
private open class KtUltraLightField(
private val declaration: KtNamedDeclaration,
name: String,
private val containingClass: KtUltraLightClass,
private val support: UltraLightSupport,
modifiers: Set<String>
) : LightFieldBuilder(name, PsiType.NULL, declaration), KtLightField {
private val modList = object : KtLightSimpleModifierList(this, modifiers) {
override fun hasModifierProperty(name: String): Boolean = when (name) {
PsiModifier.VOLATILE -> hasFieldAnnotation(VOLATILE_ANNOTATION_FQ_NAME)
PsiModifier.TRANSIENT -> hasFieldAnnotation(TRANSIENT_ANNOTATION_FQ_NAME)
else -> super.hasModifierProperty(name)
}
private fun hasFieldAnnotation(fqName: FqName): Boolean {
val annotation = support.findAnnotation(declaration, fqName)?.first ?: return false
val target = annotation.useSiteTarget?.getAnnotationUseSiteTarget() ?: return true
val expectedTarget =
if (declaration is KtProperty && declaration.hasDelegate()) AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
else AnnotationUseSiteTarget.FIELD
return target == expectedTarget
}
}
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 _type: PsiType by lazyPub {
fun nonExistent() = JavaPsiFacade.getElementFactory(project).createTypeFromText("error.NonExistentClass", declaration)
val propertyDescriptor: PropertyDescriptor? by lazyPub {
declaration.resolve() as? PropertyDescriptor
}
when {
declaration is KtProperty && declaration.hasDelegate() ->
propertyDescriptor
?.let {
val context = LightClassGenerationSupport.getInstance(project).analyze(declaration)
PropertyCodegen.getDelegateTypeForProperty(declaration, it, context)
}
?.let { it.asPsiType(support, TypeMappingMode.getOptimalModeForValueParameter(it), this) }
?.let(TypeConversionUtil::erasure)
?: nonExistent()
declaration is KtObjectDeclaration ->
KtLightClassForSourceDeclaration.create(declaration)?.let { JavaPsiFacade.getElementFactory(project).createType(it) }
?: nonExistent()
declaration is KtEnumEntry -> {
(containingClass.kotlinOrigin.resolve() as? ClassDescriptor)
?.defaultType?.asPsiType(support, TypeMappingMode.DEFAULT, this)
?: nonExistent()
}
else -> {
val kotlinType = declaration.getKotlinType() ?: return@lazyPub PsiType.NULL
val descriptor = propertyDescriptor ?: return@lazyPub PsiType.NULL
support.mapType(this) { typeMapper, sw ->
typeMapper.writeFieldSignature(kotlinType, descriptor, sw)
}
}
}
}
override fun getType(): PsiType = _type
override fun getParent() = containingClass
override fun getContainingClass() = containingClass
override fun getContainingFile(): PsiFile? = containingClass.containingFile
override fun computeConstantValue(): Any? =
if (hasModifierProperty(PsiModifier.FINAL) &&
(TypeConversionUtil.isPrimitiveAndNotNull(_type) || _type.equalsToText(CommonClassNames.JAVA_LANG_STRING))
)
(declaration.resolve() as? VariableDescriptor)?.compileTimeInitializer?.value
else null
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 {
(kotlinOrigin as? KtNamedDeclaration)?.setName(name)
return this
}
override fun setInitializer(initializer: PsiExpression?) = cannotModify()
}
private class KtUltraLightEnumEntry(
declaration: KtNamedDeclaration,
name: String,
containingClass: KtUltraLightClass,
support: UltraLightSupport,
modifiers: Set<String>
) : KtUltraLightField(declaration, name, containingClass, support, modifiers), PsiEnumConstant {
override fun getInitializingClass(): PsiEnumConstantInitializer? = null
override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer =
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 KtUltraLightMethod(
internal val delegate: LightMethodBuilder,
originalElement: KtDeclaration,
private val support: UltraLightSupport,
containingClass: KtUltraLightClass
) : KtLightMethodImpl({ delegate }, LightMemberOriginForDeclaration(originalElement, JvmDeclarationOriginKind.OTHER), containingClass) {
// 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)
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)
}
private val _throwsList: PsiReferenceList by lazyPub {
val list = KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST)
(kotlinOrigin?.resolve() as? FunctionDescriptor)?.let {
for (ex in FunctionCodegen.getThrownExceptions(it)) {
list.addReference(ex.fqNameSafe.asString())
}
}
list
}
override fun getHierarchicalMethodSignature() = PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this)
override fun getThrowsList(): PsiReferenceList = _throwsList
}
internal class KtUltraLightParameter(
name: String,
override val kotlinOrigin: KtDeclaration,
private val support: UltraLightSupport,
method: KtLightMethod,
private val receiver: KtTypeReference?,
private val containingFunction: KtCallableDeclaration
) : org.jetbrains.kotlin.asJava.elements.LightParameter(
name,
PsiType.NULL,
method,
method.language
),
KtLightDeclaration<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 isVarArgs(): Boolean =
kotlinOrigin is KtParameter && kotlinOrigin.isVarArg && method.parameterList.parameters.last() == this
override fun getModifierList(): PsiModifierList = lightModifierList
override fun getNavigationElement(): PsiElement = kotlinOrigin
override fun isValid() = parent.isValid
private val kotlinType: KotlinType? by lazyPub {
when {
receiver != null -> (kotlinOrigin.resolve() as? CallableMemberDescriptor)?.extensionReceiverParameter?.type
else -> kotlinOrigin.getKotlinType()
}
}
private val _type: PsiType by lazyPub {
val kotlinType = kotlinType ?: return@lazyPub PsiType.NULL
val containingDescriptor = containingFunction.resolve() as? CallableDescriptor ?: return@lazyPub PsiType.NULL
support.mapType(this) { typeMapper, sw ->
typeMapper.writeParameterType(sw, kotlinType, containingDescriptor)
}
}
override fun getType(): PsiType = _type
override fun setName(@NonNls name: String): PsiElement {
(kotlinOrigin as? KtVariableDeclaration)?.setName(name)
return this
}
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()
internal fun annotatedOrigin(): KtAnnotated? {
if (receiver != null) return receiver
if (kotlinOrigin is KtProperty) {
return null // we're a setter of a property with no explicit declaration, so we don't have annotation
}
return kotlinOrigin
}
internal fun getTypeForNullability(): KotlinType? {
if (receiver != null) return kotlinType
if (kotlinOrigin is KtProperty) {
if (kotlinOrigin.setter?.hasModifier(PRIVATE_KEYWORD) == true) return null
return kotlinType
}
if (kotlinOrigin is KtParameter) {
val reference = kotlinOrigin.typeReference
if (kotlinOrigin.isVarArg && reference != null) {
LightClassGenerationSupport.getInstance(project).analyze(reference)[BindingContext.TYPE, reference]?.let { return it }
}
if (reference != null || kotlinOrigin.parent?.parent is KtPropertyAccessor) {
return kotlinType
}
}
return null
}
}
interface UltraLightSupport {
val moduleName: String
fun findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>?