Add UL support for AllOpen compiler plugin
This commit is contained in:
+1
-1
@@ -90,7 +90,7 @@ internal open class KtLightClassForAnonymousDeclaration(classOrObject: KtClassOr
|
||||
|
||||
companion object {
|
||||
fun KtLightClassForSourceDeclaration.getFirstSupertypeFQNameForAnonymousDeclaration(): String {
|
||||
val descriptor = getDescriptor() ?: return CommonClassNames.JAVA_LANG_OBJECT
|
||||
val descriptor = descriptor.value ?: return CommonClassNames.JAVA_LANG_OBJECT
|
||||
|
||||
val superTypes = descriptor.typeConstructor.supertypes
|
||||
|
||||
|
||||
+18
-7
@@ -42,7 +42,10 @@ import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList
|
||||
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
@@ -53,6 +56,7 @@ import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.util.isOrdinaryClass
|
||||
import java.util.*
|
||||
import javax.swing.Icon
|
||||
|
||||
@@ -105,13 +109,12 @@ abstract class KtLightClassForSourceDeclaration(
|
||||
override val lightClassData: LightClassData
|
||||
get() = findLightClassData()
|
||||
|
||||
protected open fun findLightClassData() = getLightClassDataHolder().
|
||||
findDataForClassOrObject(classOrObject)
|
||||
protected open fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)
|
||||
|
||||
private fun getJavaFileStub(): PsiJavaFileStub = getLightClassDataHolder().javaFileStub
|
||||
|
||||
fun getDescriptor(): ClassDescriptor? {
|
||||
return LightClassGenerationSupport.getInstance(project).resolveToDescriptor(classOrObject) as? ClassDescriptor
|
||||
public val descriptor = lazyPub {
|
||||
LightClassGenerationSupport.getInstance(project).resolveToDescriptor(classOrObject) as? ClassDescriptor
|
||||
}
|
||||
|
||||
protected fun getLightClassDataHolder(): LightClassDataHolder.ForClass {
|
||||
@@ -228,7 +231,15 @@ abstract class KtLightClassForSourceDeclaration(
|
||||
if (isAbstract() || isSealed()) {
|
||||
psiModifiers.add(PsiModifier.ABSTRACT)
|
||||
} else if (!(classOrObject.hasModifier(OPEN_KEYWORD) || (classOrObject is KtClass && classOrObject.isEnum()))) {
|
||||
psiModifiers.add(PsiModifier.FINAL)
|
||||
// AllOpen can affect on modality of the member. We ought to check if the extension could override the modality
|
||||
// Resolver will produce correct descriptor corresponding to modality from AllOpen.
|
||||
// The easiest way to get new modality is to resolve the descriptor
|
||||
val modifierToAdd = if (kotlinOrigin.isOrdinaryClass && descriptor.value?.modality == Modality.OPEN) {
|
||||
PsiModifier.OPEN
|
||||
} else {
|
||||
PsiModifier.FINAL
|
||||
}
|
||||
psiModifiers.add(modifierToAdd)
|
||||
}
|
||||
|
||||
if (!classOrObject.isTopLevel() && !classOrObject.hasModifier(INNER_KEYWORD)) {
|
||||
@@ -263,13 +274,13 @@ abstract class KtLightClassForSourceDeclaration(
|
||||
LightClassInheritanceHelper.getService(project).isInheritor(this, baseClass, checkDeep).ifSure { return it }
|
||||
|
||||
val qualifiedName: String? = if (baseClass is KtLightClassForSourceDeclaration) {
|
||||
val baseDescriptor = baseClass.getDescriptor()
|
||||
val baseDescriptor = baseClass.descriptor.value
|
||||
if (baseDescriptor != null) DescriptorUtils.getFqName(baseDescriptor).asString() else null
|
||||
} else {
|
||||
baseClass.qualifiedName
|
||||
}
|
||||
|
||||
val thisDescriptor = getDescriptor()
|
||||
val thisDescriptor = descriptor.value
|
||||
return qualifiedName != null && thisDescriptor != null && checkSuperTypeByFQName(thisDescriptor, qualifiedName, checkDeep)
|
||||
}
|
||||
|
||||
|
||||
@@ -75,8 +75,6 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
|
||||
|
||||
private val _deprecated by lazyPub { classOrObject.isDeprecated(support) }
|
||||
|
||||
private val descriptor = lazyPub { getDescriptor() }
|
||||
|
||||
override fun isFinal(isFinalByPsi: Boolean) = if (tooComplex) super.isFinal(isFinalByPsi) else isFinalByPsi
|
||||
|
||||
@Volatile
|
||||
@@ -104,7 +102,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
|
||||
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||
|
||||
private fun allSuperTypes() =
|
||||
getDescriptor()?.typeConstructor?.supertypes.orEmpty()
|
||||
descriptor.value?.typeConstructor?.supertypes.orEmpty()
|
||||
|
||||
private fun mapSupertype(supertype: KotlinType, kotlinCollectionAsIs: Boolean = false) =
|
||||
supertype.asPsiType(
|
||||
|
||||
+68
-46
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.classes
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder
|
||||
import com.intellij.psi.impl.light.LightModifierList
|
||||
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.asJava.elements.convertToLightAnnotationMemberValue
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.REIFIED_KEYWORD
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
@@ -26,6 +28,7 @@ import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
||||
@@ -35,6 +38,7 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_
|
||||
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.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
import org.jetbrains.kotlin.util.isOrdinaryClass
|
||||
|
||||
internal class UltraLightMembersCreator(
|
||||
private val containingClass: KtLightClass,
|
||||
@@ -232,6 +236,69 @@ internal class UltraLightMembersCreator(
|
||||
private fun DeclarationDescriptor.getterIfProperty() =
|
||||
if (this@getterIfProperty is PropertyDescriptor) this@getterIfProperty.getter else this@getterIfProperty
|
||||
|
||||
private inner class UltraLightModifierListForMember(
|
||||
private val declaration: KtDeclaration,
|
||||
private val accessedProperty: KtProperty?,
|
||||
private val outerDeclaration: KtDeclaration,
|
||||
private val forceStatic: Boolean,
|
||||
private val forcePrivate: Boolean = false
|
||||
) : LightModifierList(declaration.manager, declaration.language) {
|
||||
|
||||
override fun hasModifierProperty(name: String): Boolean {
|
||||
|
||||
val modifierResult = hasModifier(name)
|
||||
|
||||
//AllOpen can affect on modality of the member. We ought to check if the extension could override the modality
|
||||
if (name != PsiModifier.FINAL) return modifierResult
|
||||
if (!outerDeclaration.isOrdinaryClass) return modifierResult
|
||||
// Resolver will produce correct descriptor corresponding to modality from AllOpen.
|
||||
// The easiest way to get new modality is to resolve the descriptor
|
||||
return (declaration.resolve() as? CallableMemberDescriptor)?.modality == Modality.FINAL
|
||||
}
|
||||
|
||||
private fun hasModifier(name: String): Boolean {
|
||||
if (name == PsiModifier.PUBLIC || name == PsiModifier.PROTECTED || name == PsiModifier.PRIVATE) {
|
||||
if (forcePrivate || declaration.isPrivate() || accessedProperty?.isPrivate() == true) {
|
||||
return name == PsiModifier.PRIVATE
|
||||
}
|
||||
if (declaration.hasModifier(KtTokens.PROTECTED_KEYWORD) || accessedProperty?.hasModifier(KtTokens.PROTECTED_KEYWORD) == true) {
|
||||
return name == PsiModifier.PROTECTED
|
||||
}
|
||||
|
||||
if (outerDeclaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) {
|
||||
when ((outerDeclaration.resolve() as? CallableDescriptor)?.visibility) {
|
||||
Visibilities.PUBLIC -> return name == PsiModifier.PUBLIC
|
||||
Visibilities.PRIVATE -> return name == PsiModifier.PRIVATE
|
||||
Visibilities.PROTECTED -> return name == PsiModifier.PROTECTED
|
||||
}
|
||||
}
|
||||
|
||||
return name == PsiModifier.PUBLIC
|
||||
}
|
||||
|
||||
return when (name) {
|
||||
PsiModifier.FINAL -> !containingClass.isInterface && outerDeclaration !is KtConstructor<*> && isFinal(outerDeclaration)
|
||||
PsiModifier.ABSTRACT -> containingClass.isInterface || outerDeclaration.hasModifier(KtTokens.ABSTRACT_KEYWORD)
|
||||
PsiModifier.STATIC -> forceStatic || containingClassIsNamedObject && (outerDeclaration.isJvmStatic(support) || declaration.isJvmStatic(support))
|
||||
PsiModifier.STRICTFP -> declaration is KtFunction && declaration.hasAnnotation(STRICTFP_ANNOTATION_FQ_NAME)
|
||||
PsiModifier.SYNCHRONIZED -> declaration is KtFunction && declaration.hasAnnotation(SYNCHRONIZED_ANNOTATION_FQ_NAME)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtDeclaration.isPrivate() =
|
||||
hasModifier(KtTokens.PRIVATE_KEYWORD) || this is KtConstructor<*> && containingClassIsSealed || isInlineOnly()
|
||||
|
||||
private fun KtDeclaration.isInlineOnly(): Boolean {
|
||||
if (this !is KtCallableDeclaration || !hasModifier(KtTokens.INLINE_KEYWORD)) return false
|
||||
if (annotationEntries.isEmpty()) return false
|
||||
|
||||
val descriptor = resolve() as? CallableMemberDescriptor ?: return false
|
||||
|
||||
return descriptor.isInlineOnly()
|
||||
}
|
||||
}
|
||||
|
||||
private fun lightMethod(
|
||||
name: String,
|
||||
declaration: KtDeclaration,
|
||||
@@ -247,52 +314,7 @@ internal class UltraLightMembersCreator(
|
||||
return LightMethodBuilder(
|
||||
manager, language, name,
|
||||
LightParameterListBuilder(manager, language),
|
||||
object : LightModifierList(manager, language) {
|
||||
override fun hasModifierProperty(name: String): Boolean {
|
||||
if (name == PsiModifier.PUBLIC || name == PsiModifier.PROTECTED || name == PsiModifier.PRIVATE) {
|
||||
if (forcePrivate || declaration.isPrivate() || accessedProperty?.isPrivate() == true) {
|
||||
return name == PsiModifier.PRIVATE
|
||||
}
|
||||
if (declaration.hasModifier(KtTokens.PROTECTED_KEYWORD) || accessedProperty?.hasModifier(KtTokens.PROTECTED_KEYWORD) == true) {
|
||||
return name == PsiModifier.PROTECTED
|
||||
}
|
||||
|
||||
if (outer.hasModifier(KtTokens.OVERRIDE_KEYWORD)) {
|
||||
when ((outer.resolve() as? CallableDescriptor)?.visibility) {
|
||||
Visibilities.PUBLIC -> return name == PsiModifier.PUBLIC
|
||||
Visibilities.PRIVATE -> return name == PsiModifier.PRIVATE
|
||||
Visibilities.PROTECTED -> return name == PsiModifier.PROTECTED
|
||||
}
|
||||
}
|
||||
|
||||
return name == PsiModifier.PUBLIC
|
||||
}
|
||||
|
||||
return when (name) {
|
||||
PsiModifier.FINAL -> !containingClass.isInterface && outer !is KtConstructor<*> && isFinal(outer)
|
||||
PsiModifier.ABSTRACT -> containingClass.isInterface || outer.hasModifier(KtTokens.ABSTRACT_KEYWORD)
|
||||
PsiModifier.STATIC -> forceStatic || containingClassIsNamedObject && (outer.isJvmStatic(support) || declaration.isJvmStatic(
|
||||
support
|
||||
))
|
||||
PsiModifier.STRICTFP -> declaration is KtFunction && declaration.hasAnnotation(STRICTFP_ANNOTATION_FQ_NAME)
|
||||
PsiModifier.SYNCHRONIZED -> declaration is KtFunction && declaration.hasAnnotation(SYNCHRONIZED_ANNOTATION_FQ_NAME)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
fun KtDeclaration.isPrivate() =
|
||||
hasModifier(KtTokens.PRIVATE_KEYWORD) ||
|
||||
this is KtConstructor<*> && containingClassIsSealed || isInlineOnly()
|
||||
|
||||
private fun KtDeclaration.isInlineOnly(): Boolean {
|
||||
if (this !is KtCallableDeclaration || !hasModifier(KtTokens.INLINE_KEYWORD)) return false
|
||||
if (annotationEntries.isEmpty()) return false
|
||||
|
||||
val descriptor = resolve() as? CallableMemberDescriptor ?: return false
|
||||
|
||||
return descriptor.isInlineOnly()
|
||||
}
|
||||
}
|
||||
UltraLightModifierListForMember(declaration, accessedProperty, outer, forceStatic, forcePrivate)
|
||||
).setConstructor(declaration is KtConstructor<*>)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user