diff --git a/analysis/decompiled/light-classes-for-decompiled/build.gradle.kts b/analysis/decompiled/light-classes-for-decompiled/build.gradle.kts new file mode 100644 index 00000000000..6a376e39fc1 --- /dev/null +++ b/analysis/decompiled/light-classes-for-decompiled/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + kotlin("jvm") + id("jps-compatible") +} + +dependencies { + api(project(":compiler:psi")) + api(project(":analysis:decompiled:decompiler-to-psi")) + api(project(":compiler:light-classes")) + implementation(intellijCore()) +} + +sourceSets { + "main" { projectDefault() } + "test" { none() } +} diff --git a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclaration.kt b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclaration.kt new file mode 100644 index 00000000000..2413db64e14 --- /dev/null +++ b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclaration.kt @@ -0,0 +1,231 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.jetbrains.kotlin.analysis.decompiled.light.classes + +import com.intellij.openapi.util.Pair +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.javadoc.PsiDocComment +import com.intellij.psi.scope.PsiScopeProcessor +import com.intellij.psi.util.PsiUtil +import org.jetbrains.annotations.NonNls +import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.LightMemberOriginForCompiledField +import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.LightMemberOriginForCompiledMethod +import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile +import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService +import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache +import org.jetbrains.kotlin.asJava.classes.LightClassesLazyCreator +import org.jetbrains.kotlin.asJava.classes.lazyPub +import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind +import org.jetbrains.kotlin.psi.KtClassOrObject + +open class KtLightClassForDecompiledDeclaration( + override val clsDelegate: PsiClass, + private val clsParent: PsiElement, + private val file: KtClsFile, + kotlinOrigin: KtClassOrObject? +) : KtLightClassForDecompiledDeclarationBase(clsDelegate, clsParent, kotlinOrigin) { + + private val myInnersCache = KotlinClassInnerStuffCache( + myClass = this, + externalDependencies = listOf(KotlinModificationTrackerService.getInstance(manager.project).outOfBlockModificationTracker), + lazyCreator = LightClassesLazyCreator(project) + ) + + override fun getOwnMethods(): MutableList = _methods + + override fun getOwnFields(): MutableList = _fields + + override fun getOwnInnerClasses(): MutableList = _innerClasses + + override fun getFields() = myInnersCache.fields + + override fun getMethods() = myInnersCache.methods + + override fun getConstructors() = myInnersCache.constructors + + override fun getInnerClasses() = myInnersCache.innerClasses + + override fun findFieldByName(name: String, checkBases: Boolean) = myInnersCache.findFieldByName(name, checkBases) + + override fun findMethodsByName(name: String, checkBases: Boolean) = myInnersCache.findMethodsByName(name, checkBases) + + override fun findInnerClassByName(name: String, checkBases: Boolean) = myInnersCache.findInnerClassByName(name, checkBases) + + override fun hasModifierProperty(name: String): Boolean = + clsDelegate.hasModifierProperty(name) + + override fun findMethodBySignature(patternMethod: PsiMethod?, checkBases: Boolean): PsiMethod? = + patternMethod?.let { PsiClassImplUtil.findMethodBySignature(this, it, checkBases) } + + override fun findMethodsBySignature(patternMethod: PsiMethod?, checkBases: Boolean): Array = + patternMethod?.let { PsiClassImplUtil.findMethodsBySignature(this, it, checkBases) } ?: emptyArray() + + override fun findMethodsAndTheirSubstitutorsByName(@NonNls name: String?, checkBases: Boolean): List> = + PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases) + + override fun getImplementsList(): PsiReferenceList? = clsDelegate.implementsList + + override fun getRBrace(): PsiElement? = null + + override fun getLBrace(): PsiElement? = null + + override fun getInitializers(): Array = clsDelegate.initializers + + override fun getContainingClass(): PsiClass? = parent as? PsiClass + + override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = clsDelegate.isInheritorDeep(baseClass, classToByPass) + + override fun getAllMethodsAndTheirSubstitutors(): List?> = + PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiClassImplUtil.MemberType.METHOD) + + override fun isInterface(): Boolean = clsDelegate.isInterface + + override fun getTypeParameters(): Array = + clsDelegate.typeParameters + + override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = + clsDelegate.isInheritor(baseClass, checkDeep) + + override fun processDeclarations( + processor: PsiScopeProcessor, + state: ResolveState, + lastParent: PsiElement?, + place: PsiElement + ): Boolean { + if (isEnum) { + if (!KotlinClassInnerStuffCache.processDeclarationsInEnum(processor, state, myInnersCache)) return false + } + return PsiClassImplUtil.processDeclarationsInClass( + this, processor, state, null, + lastParent, place, PsiUtil.getLanguageLevel(place), false + ) + } + + override fun isEnum(): Boolean = clsDelegate.isEnum + + override fun getExtendsListTypes(): Array = + PsiClassImplUtil.getExtendsListTypes(this) + + override fun getTypeParameterList(): PsiTypeParameterList? = clsDelegate.typeParameterList + + override fun isAnnotationType(): Boolean = clsDelegate.isAnnotationType + + override fun getNameIdentifier(): PsiIdentifier? = clsDelegate.nameIdentifier + + override fun getInterfaces(): Array = + PsiClassImplUtil.getInterfaces(this) + + override fun getSuperClass(): PsiClass? = + PsiClassImplUtil.getSuperClass(this) + + override fun getSupers(): Array = + PsiClassImplUtil.getSupers(this) + + override fun getSuperTypes(): Array = + PsiClassImplUtil.getSuperTypes(this) + + override fun getVisibleSignatures(): MutableCollection = + PsiSuperMethodImplUtil.getVisibleSignatures(this) + + override fun getQualifiedName(): String? = clsDelegate.qualifiedName + + override fun getImplementsListTypes(): Array = + PsiClassImplUtil.getImplementsListTypes(this) + + override fun isDeprecated(): Boolean = clsDelegate.isDeprecated + + override fun setName(name: String): PsiElement = clsDelegate.setName(name) + + override fun hasTypeParameters(): Boolean = + PsiImplUtil.hasTypeParameters(this) + + override fun getExtendsList(): PsiReferenceList? = clsDelegate.extendsList + + override fun getDocComment(): PsiDocComment? = clsDelegate.docComment + + override fun getModifierList(): PsiModifierList? = clsDelegate.modifierList + + override fun getScope(): PsiElement = clsDelegate.scope + + override fun getAllInnerClasses(): Array = PsiClassImplUtil.getAllInnerClasses(this) + + override fun getAllMethods(): Array = PsiClassImplUtil.getAllMethods(this) + + override fun getAllFields(): Array = PsiClassImplUtil.getAllFields(this) + + private val _methods: MutableList by lazyPub { + mutableListOf().also { + clsDelegate.methods.mapTo(it) { psiMethod -> + KtLightMethodForDecompiledDeclaration( + funDelegate = psiMethod, + funParent = this, + lightMemberOrigin = LightMemberOriginForCompiledMethod(psiMethod, file) + ) + } + } + } + + private val _fields: MutableList by lazyPub { + mutableListOf().also { + clsDelegate.fields.mapTo(it) { psiField -> + if (psiField !is PsiEnumConstant) { + KtLightFieldForDecompiledDeclaration( + fldDelegate = psiField, + fldParent = this, + lightMemberOrigin = LightMemberOriginForCompiledField(psiField, file) + ) + } else { + KtLightEnumEntryForDecompiledDeclaration( + fldDelegate = psiField, + fldParent = this, + lightMemberOrigin = LightMemberOriginForCompiledField(psiField, file), + file = file + ) + } + } + } + } + + private val _innerClasses: MutableList by lazyPub { + mutableListOf().also { + clsDelegate.innerClasses.mapTo(it) { psiClass -> + val innerDeclaration = kotlinOrigin + ?.declarations + ?.filterIsInstance() + ?.firstOrNull { cls -> cls.name == clsDelegate.name } + + KtLightClassForDecompiledDeclaration( + clsDelegate = psiClass, + clsParent = this, + file = file, + kotlinOrigin = innerDeclaration, + ) + } + } + } + + override val originKind: LightClassOriginKind = LightClassOriginKind.BINARY + + override fun getNavigationElement() = kotlinOrigin?.navigationElement ?: file + + override fun equals(other: Any?): Boolean { + return this === other || other is KtLightClassForDecompiledDeclaration && + qualifiedName == other.qualifiedName && + kotlinOrigin?.fqName == other.kotlinOrigin?.fqName + } + + override fun hashCode(): Int = qualifiedName?.hashCode() ?: kotlinOrigin?.fqName?.hashCode() ?: 0 + + override fun copy(): PsiElement = this + + override fun clone(): Any = this + + override fun toString(): String = "${this.javaClass.simpleName} of $parent" + + override fun getName(): String? = clsDelegate.name + + override fun isValid(): Boolean = file.isValid && clsDelegate.isValid && (kotlinOrigin?.isValid != false) +} \ No newline at end of file diff --git a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclarationBase.kt b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclarationBase.kt new file mode 100644 index 00000000000..cbfb5732de0 --- /dev/null +++ b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclarationBase.kt @@ -0,0 +1,16 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.jetbrains.kotlin.analysis.decompiled.light.classes + +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.impl.source.PsiExtensibleClass +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.elements.KtLightElementBase +import org.jetbrains.kotlin.psi.KtClassOrObject + +abstract class KtLightClassForDecompiledDeclarationBase( + override val clsDelegate: PsiClass, + clsParent: PsiElement, + final override val kotlinOrigin: KtClassOrObject? +) : KtLightElementBase(clsParent), PsiClass, KtLightClass, PsiExtensibleClass \ No newline at end of file diff --git a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightEnumClassForDecompiledDeclaration.kt b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightEnumClassForDecompiledDeclaration.kt new file mode 100644 index 00000000000..2666479fae6 --- /dev/null +++ b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightEnumClassForDecompiledDeclaration.kt @@ -0,0 +1,35 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.jetbrains.kotlin.analysis.decompiled.light.classes + +import com.intellij.psi.* +import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile +import org.jetbrains.kotlin.psi.KtClassOrObject + +internal class KtLightEnumClassForDecompiledDeclaration( + private val psiConstantInitializer: PsiEnumConstantInitializer, + private val enumConstant: KtLightEnumEntryForDecompiledDeclaration, + clsParent: KtLightClassForDecompiledDeclaration, + file: KtClsFile, + kotlinOrigin: KtClassOrObject? +) : + KtLightClassForDecompiledDeclaration( + clsDelegate = psiConstantInitializer, + clsParent = clsParent, + file = file, + kotlinOrigin = kotlinOrigin + ), PsiEnumConstantInitializer { + + override fun getBaseClassType(): PsiClassType = psiConstantInitializer.baseClassType + + override fun getArgumentList(): PsiExpressionList? = psiConstantInitializer.argumentList + + override fun getEnumConstant(): PsiEnumConstant = enumConstant + + override fun getBaseClassReference(): PsiJavaCodeReferenceElement = psiConstantInitializer.baseClassReference + + override fun isInQualifiedNew(): Boolean = psiConstantInitializer.isInQualifiedNew + + override fun equals(other: Any?): Boolean = other is KtLightEnumClassForDecompiledDeclaration && super.equals(other) + override fun hashCode(): Int = super.hashCode() +} \ No newline at end of file diff --git a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightEnumEntryForDecompiledDeclaration.kt b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightEnumEntryForDecompiledDeclaration.kt new file mode 100644 index 00000000000..8246d5ea034 --- /dev/null +++ b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightEnumEntryForDecompiledDeclaration.kt @@ -0,0 +1,43 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.jetbrains.kotlin.analysis.decompiled.light.classes + +import com.intellij.psi.* +import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.LightMemberOriginForCompiledField +import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile +import org.jetbrains.kotlin.asJava.classes.lazyPub + +internal class KtLightEnumEntryForDecompiledDeclaration( + private val fldDelegate: PsiEnumConstant, + fldParent: KtLightClassForDecompiledDeclaration, + lightMemberOrigin: LightMemberOriginForCompiledField, + file: KtClsFile, +) : KtLightFieldForDecompiledDeclaration( + fldDelegate, + fldParent, + lightMemberOrigin +), PsiEnumConstant { + + private val _initializingClass: PsiEnumConstantInitializer? by lazyPub { + fldDelegate.initializingClass?.let { + KtLightEnumClassForDecompiledDeclaration( + psiConstantInitializer = it, + enumConstant = this, + clsParent = fldParent, + file = file, + kotlinOrigin = null + ) + } + } + + override fun getArgumentList(): PsiExpressionList? = fldDelegate.argumentList + override fun resolveConstructor(): PsiMethod? = fldDelegate.resolveConstructor() + override fun resolveMethod(): PsiMethod? = fldDelegate.resolveMethod() + override fun resolveMethodGenerics(): JavaResolveResult = fldDelegate.resolveMethodGenerics() + override fun getInitializingClass(): PsiEnumConstantInitializer? = _initializingClass + override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer = + _initializingClass ?: error("cannot create initializing class in light enum constant") + + override fun equals(other: Any?): Boolean = other is KtLightEnumEntryForDecompiledDeclaration && super.equals(other) + override fun hashCode(): Int = super.hashCode() +} \ No newline at end of file diff --git a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightFieldForDecompiledDeclaration.kt b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightFieldForDecompiledDeclaration.kt new file mode 100644 index 00000000000..c619d578dd7 --- /dev/null +++ b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightFieldForDecompiledDeclaration.kt @@ -0,0 +1,73 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.jetbrains.kotlin.analysis.decompiled.light.classes + +import com.intellij.psi.* +import com.intellij.psi.impl.PsiVariableEx +import com.intellij.psi.javadoc.PsiDocComment +import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.LightMemberOriginForCompiledField +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.elements.KtLightElementBase +import org.jetbrains.kotlin.asJava.elements.KtLightFieldForSourceDeclarationSupport +import org.jetbrains.kotlin.asJava.elements.KtLightMember +import org.jetbrains.kotlin.psi.KtDeclaration + +open class KtLightFieldForDecompiledDeclaration( + private val fldDelegate: PsiField, + private val fldParent: KtLightClass, + override val lightMemberOrigin: LightMemberOriginForCompiledField +) : KtLightElementBase(fldParent), PsiField, KtLightFieldForSourceDeclarationSupport, KtLightMember, PsiVariableEx { + + override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin.originalElement + + override fun hasModifierProperty(name: String): Boolean = fldDelegate.hasModifierProperty(name) + + override fun setInitializer(initializer: PsiExpression?) { + fldDelegate.initializer = initializer + } + + override fun getContainingClass(): KtLightClass = fldParent + + override fun normalizeDeclaration() = fldDelegate.normalizeDeclaration() + + override fun getNameIdentifier(): PsiIdentifier = fldDelegate.nameIdentifier + + override fun getName(): String = fldDelegate.name + + override fun getInitializer(): PsiExpression? = fldDelegate.initializer + + override fun getDocComment(): PsiDocComment? = fldDelegate.docComment + + override fun getTypeElement(): PsiTypeElement? = fldDelegate.typeElement + + override fun getModifierList(): PsiModifierList? = fldDelegate.modifierList + + override fun hasInitializer(): Boolean = fldDelegate.hasInitializer() + + override fun getType(): PsiType = fldDelegate.type + + override fun isDeprecated(): Boolean = fldDelegate.isDeprecated + + override fun setName(name: String): PsiElement = fldDelegate.setName(name) + + override fun computeConstantValue(): Any? = fldDelegate.computeConstantValue() + + override fun computeConstantValue(visitedVars: MutableSet?): Any? = (fldDelegate as? PsiVariableEx)?.computeConstantValue(visitedVars) + + override fun equals(other: Any?): Boolean = other is KtLightFieldForDecompiledDeclaration && + name == other.name && + fldParent == other.fldParent && + fldDelegate == other.fldDelegate + + override fun hashCode(): Int = name.hashCode() + + override fun copy(): PsiElement = this + + override fun clone(): Any = this + + override fun toString(): String = "${this.javaClass.simpleName} of $fldParent" + + override val clsDelegate: PsiField = fldDelegate + + override fun isValid(): Boolean = parent.isValid +} \ No newline at end of file diff --git a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightMethodForDecompiledDeclaration.kt b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightMethodForDecompiledDeclaration.kt new file mode 100644 index 00000000000..014646fd15d --- /dev/null +++ b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightMethodForDecompiledDeclaration.kt @@ -0,0 +1,109 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.jetbrains.kotlin.analysis.decompiled.light.classes + +import com.intellij.psi.* +import com.intellij.psi.impl.PsiSuperMethodImplUtil +import com.intellij.psi.javadoc.PsiDocComment +import com.intellij.psi.util.MethodSignature +import com.intellij.psi.util.MethodSignatureBackedByPsiMethod +import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.LightMemberOriginForCompiledMethod +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.elements.KtLightElementBase +import org.jetbrains.kotlin.asJava.elements.KtLightMember +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.asJava.propertyNameByAccessor +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.psi.KtDeclaration + +class KtLightMethodForDecompiledDeclaration( + private val funDelegate: PsiMethod, + private val funParent: KtLightClass, + override val lightMemberOrigin: LightMemberOriginForCompiledMethod, +) : KtLightElementBase(funParent), PsiMethod, KtLightMethod, KtLightMember { + + override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin.originalElement + + override val isMangled: Boolean get() = checkIsMangled() + + override fun hasModifierProperty(name: String): Boolean = funDelegate.hasModifierProperty(name) + + override fun getReturnTypeElement(): PsiTypeElement? = funDelegate.returnTypeElement + + override fun getContainingClass(): KtLightClass = funParent + + override fun getTypeParameters(): Array = funDelegate.typeParameters + + override fun getThrowsList(): PsiReferenceList = funDelegate.throwsList + + override fun getReturnType(): PsiType? = funDelegate.returnType + + override fun hasTypeParameters(): Boolean = funDelegate.hasTypeParameters() + + override fun getTypeParameterList(): PsiTypeParameterList? = funDelegate.typeParameterList + + override fun isVarArgs(): Boolean = funDelegate.isVarArgs + + override fun isConstructor(): Boolean = funDelegate.isConstructor + + override fun getNameIdentifier(): PsiIdentifier? = funDelegate.nameIdentifier + + override fun getName(): String = funDelegate.name + + override fun getDocComment(): PsiDocComment? = funDelegate.docComment + + override fun getModifierList(): PsiModifierList = funDelegate.modifierList + + override fun getBody(): PsiCodeBlock? = null + + override fun getDefaultValue(): PsiAnnotationMemberValue? = (funDelegate as? PsiAnnotationMethod)?.defaultValue + + override fun isDeprecated(): Boolean = funDelegate.isDeprecated + + override fun setName(name: String): PsiElement = funDelegate.setName(name) + + override fun getParameterList(): PsiParameterList = funDelegate.parameterList + + override fun getHierarchicalMethodSignature() = PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this) + + override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean): List = + PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess) + + override fun findDeepestSuperMethod() = PsiSuperMethodImplUtil.findDeepestSuperMethod(this) + + override fun findDeepestSuperMethods(): Array = PsiSuperMethodImplUtil.findDeepestSuperMethods(this) + + override fun findSuperMethods(): Array = PsiSuperMethodImplUtil.findSuperMethods(this) + + override fun findSuperMethods(checkAccess: Boolean): Array = + PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess) + + override fun findSuperMethods(parentClass: PsiClass?): Array = + PsiSuperMethodImplUtil.findSuperMethods(this, parentClass) + + override fun getSignature(substitutor: PsiSubstitutor): MethodSignature = + MethodSignatureBackedByPsiMethod.create(this, substitutor) + + override fun equals(other: Any?): Boolean = other is KtLightMethodForDecompiledDeclaration && + name == other.name && + funParent == other.funParent && + funDelegate == other.funDelegate + + override fun hashCode(): Int = name.hashCode() + + override fun copy(): PsiElement = this + + override fun clone(): Any = this + + override fun toString(): String = "${this.javaClass.simpleName} of $funParent" + + override val clsDelegate: PsiMethod = funDelegate + + override fun isValid(): Boolean = parent.isValid +} + +private fun KtLightMethod.checkIsMangled(): Boolean { + val demangledName = KotlinTypeMapper.InternalNameMapper.demangleInternalName(name) ?: return false + val originalName = propertyNameByAccessor(demangledName, this) ?: demangledName + return originalName == kotlinOrigin?.name +} \ No newline at end of file diff --git a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/origin/LightMemberOriginForCompiledElement.kt b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/origin/LightMemberOriginForCompiledElement.kt new file mode 100644 index 00000000000..105efcc73a0 --- /dev/null +++ b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/origin/LightMemberOriginForCompiledElement.kt @@ -0,0 +1,75 @@ +package org.jetbrains.kotlin.analysis.decompiled.light.classes.origin + + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiField +import com.intellij.psi.PsiMember +import com.intellij.psi.PsiMethod +import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile +import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin +import org.jetbrains.kotlin.asJava.classes.lazyPub +import org.jetbrains.kotlin.load.kotlin.MemberSignature +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind +import org.jetbrains.kotlin.type.MapPsiToAsmDesc + +interface LightMemberOriginForCompiledElement : LightMemberOrigin { + val member: T + + override val originKind: JvmDeclarationOriginKind + get() = JvmDeclarationOriginKind.OTHER + + override fun isEquivalentTo(other: PsiElement?): Boolean { + return when (other) { + is KtDeclaration -> originalElement?.isEquivalentTo(other) ?: false + is PsiMember -> member.isEquivalentTo(other) + else -> false + } + } + + override fun isValid(): Boolean = member.isValid +} + + +data class LightMemberOriginForCompiledField(val psiField: PsiField, val file: KtClsFile) : LightMemberOriginForCompiledElement { + override val member: PsiField + get() = psiField + + override fun copy(): LightMemberOrigin { + return LightMemberOriginForCompiledField(psiField.copy() as PsiField, file) + } + + override fun isEquivalentTo(other: LightMemberOrigin?): Boolean { + if (other !is LightMemberOriginForCompiledField) return false + return psiField.isEquivalentTo(other.psiField) + } + + override val originalElement: KtDeclaration? by lazyPub { + val desc = MapPsiToAsmDesc.typeDesc(psiField.type) + val signature = MemberSignature.fromFieldNameAndDesc(psiField.name, desc) + findDeclarationInCompiledFile(file, psiField, signature) + } +} + +data class LightMemberOriginForCompiledMethod(val psiMethod: PsiMethod, val file: KtClsFile) : + LightMemberOriginForCompiledElement { + + override val member: PsiMethod + get() = psiMethod + + override fun isEquivalentTo(other: LightMemberOrigin?): Boolean { + if (other !is LightMemberOriginForCompiledMethod) return false + return psiMethod.isEquivalentTo(other.psiMethod) + } + + override fun copy(): LightMemberOrigin { + return LightMemberOriginForCompiledMethod(psiMethod.copy() as PsiMethod, file) + } + + override val originalElement: KtDeclaration? by lazyPub { + val desc = MapPsiToAsmDesc.methodDesc(psiMethod) + val name = if (psiMethod.isConstructor) "" else psiMethod.name + val signature = MemberSignature.fromMethodNameAndDesc(name, desc) + findDeclarationInCompiledFile(file, psiMethod, signature) + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 9fce8fbdf73..f59eefbf41b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -499,7 +499,8 @@ include ":generators:analysis-api-generator", ":analysis:symbol-light-classes", ":analysis:project-structure", ":analysis:analysis-api-fe10", - ":analysis:decompiled:decompiler-to-psi" + ":analysis:decompiled:decompiler-to-psi", + ":analysis:decompiled:light-classes-for-decompiled" if (buildProperties.inJpsBuildIdeaSync) {