Minor. Split ultraLightPsi.kt into three files
By one for PsiClass, PsiField and PsiMethod implementations
This commit is contained in:
@@ -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>?
|
||||
|
||||
Reference in New Issue
Block a user