diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMethodImpl.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMethodImpl.kt index 3e2a7bfa4ae..d58778f90e7 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMethodImpl.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMethodImpl.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration import org.jetbrains.kotlin.asJava.builder.MemberIndex import org.jetbrains.kotlin.asJava.builder.memberIndex +import org.jetbrains.kotlin.asJava.checkIsMangled import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.cannotModify import org.jetbrains.kotlin.asJava.classes.lazyPub @@ -89,12 +90,7 @@ open class KtLightMethodImpl protected constructor( } } - override val isMangled: Boolean - get() { - val demangledName = KotlinTypeMapper.InternalNameMapper.demangleInternalName(name) ?: return false - val originalName = propertyNameByAccessor(demangledName, this) ?: demangledName - return originalName == kotlinOrigin?.name - } + override val isMangled: Boolean get() = checkIsMangled() override fun setName(name: String): PsiElement? { val jvmNameAnnotation = modifierList.findAnnotation(DescriptorUtils.JVM_NAME.asString()) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt index e0c755e7e73..35e68f33e9e 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.elements.PsiElementWithOrigin import org.jetbrains.kotlin.asJava.elements.* import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.propertyNameByGetMethodName import org.jetbrains.kotlin.load.java.propertyNameBySetMethodName @@ -213,4 +214,10 @@ fun accessorNameByPropertyName(name: String, accessor: KtLightMethod): String? { fun getAccessorNamesCandidatesByPropertyName(name: String): List { return listOf(JvmAbi.setterName(name), JvmAbi.getterName(name)) +} + +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/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/KtLightClassForDecompiledDeclaration.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/KtLightClassForDecompiledDeclaration.kt deleted file mode 100644 index 8fb08f37718..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/KtLightClassForDecompiledDeclaration.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.idea.caches.lightClasses - -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiField -import com.intellij.psi.PsiMethod -import com.intellij.psi.impl.compiled.ClsClassImpl -import org.jetbrains.kotlin.asJava.classes.KtLightClassBase -import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl -import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl -import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile -import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtClassOrObject - -class KtLightClassForDecompiledDeclaration( - override val clsDelegate: ClsClassImpl, - override val kotlinOrigin: KtClassOrObject?, - private val file: KtClsFile -) : KtLightClassBase(clsDelegate.manager) { - val fqName = kotlinOrigin?.fqName ?: FqName(clsDelegate.qualifiedName.orEmpty()) - - override fun copy() = this - - override fun getOwnInnerClasses(): List { - val nestedClasses = kotlinOrigin?.declarations?.filterIsInstance() ?: emptyList() - return clsDelegate.ownInnerClasses.map { innerClsClass -> - KtLightClassForDecompiledDeclaration( - innerClsClass as ClsClassImpl, - nestedClasses.firstOrNull { innerClsClass.name == it.name }, file - ) - } - } - - override fun getOwnFields(): List { - return clsDelegate.ownFields.map { KtLightFieldImpl.create(LightMemberOriginForCompiledField(it, file), it, this) } - } - - override fun getOwnMethods(): List { - return clsDelegate.ownMethods.map { KtLightMethodImpl.create(it, LightMemberOriginForCompiledMethod(it, file), this) } - } - - override fun getNavigationElement() = kotlinOrigin?.navigationElement ?: file - - override fun getParent() = clsDelegate.parent - - override fun equals(other: Any?): Boolean = - other is KtLightClassForDecompiledDeclaration && - fqName == other.fqName - - override fun hashCode(): Int = - fqName.hashCode() - - override val originKind: LightClassOriginKind - get() = LightClassOriginKind.BINARY -} - diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/LightMemberOriginForCompiledElement.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/LightMemberOriginForCompiledElement.kt index dddf0e49a1d..75f9be4d052 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/LightMemberOriginForCompiledElement.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/LightMemberOriginForCompiledElement.kt @@ -101,7 +101,7 @@ data class LightMemberOriginForCompiledMethod(val psiMethod: PsiMethod, val file } } -private fun findDeclarationInCompiledFile(file: KtClsFile, member: PsiMember, signature: MemberSignature): KtDeclaration? { +internal fun findDeclarationInCompiledFile(file: KtClsFile, member: PsiMember, signature: MemberSignature): KtDeclaration? { val relativeClassName = member.relativeClassName() val key = ClassNameAndSignature(relativeClassName, signature) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightClassForDecompiledDeclaration.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightClassForDecompiledDeclaration.kt new file mode 100644 index 00000000000..58f3f7bb25f --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightClassForDecompiledDeclaration.kt @@ -0,0 +1,233 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.caches.lightClasses + +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.impl.source.PsiExtensibleClass +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.analyzer.KotlinModificationTrackerService +import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.classes.lazyPub +import org.jetbrains.kotlin.asJava.elements.KtLightElementBase +import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile +import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.idea.caches.lightClasses.decompiledDeclarations.* + +open class KtLightClassForDecompiledDeclaration( + override val clsDelegate: PsiClass, + private val clsParent: PsiElement, + private val file: KtClsFile, + final override val kotlinOrigin: KtClassOrObject? +) : KtLightElementBase(clsParent), PsiClass, KtLightClass, PsiExtensibleClass { + + private val myInnersCache = KotlinClassInnerStuffCache( + myClass = this, + externalDependencies = listOf(KotlinModificationTrackerService.getInstance(manager.project).outOfBlockModificationTracker) + ) + + 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 = + other is KtLightClassForDecompiledDeclaration && + qualifiedName == other.qualifiedName && + kotlinOrigin?.fqName == other.kotlinOrigin?.fqName + + override fun hashCode(): Int = clsDelegate.hashCode() + + 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/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightEnumClassForDecompiledDeclaration.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightEnumClassForDecompiledDeclaration.kt new file mode 100644 index 00000000000..c5371fd3682 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightEnumClassForDecompiledDeclaration.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.caches.lightClasses.decompiledDeclarations + +import com.intellij.psi.* +import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration +import org.jetbrains.kotlin.idea.decompiler.classFile.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/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightEnumEntryForDecompiledDeclaration.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightEnumEntryForDecompiledDeclaration.kt new file mode 100644 index 00000000000..5aa3b4559a3 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightEnumEntryForDecompiledDeclaration.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.caches.lightClasses.decompiledDeclarations + +import com.intellij.psi.* +import org.jetbrains.kotlin.asJava.classes.lazyPub +import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration +import org.jetbrains.kotlin.idea.caches.lightClasses.LightMemberOriginForCompiledField +import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile + +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/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightFieldForDecompiledDeclaration.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightFieldForDecompiledDeclaration.kt new file mode 100644 index 00000000000..58980801dbf --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightFieldForDecompiledDeclaration.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.caches.lightClasses.decompiledDeclarations + +import com.intellij.psi.* +import com.intellij.psi.impl.PsiVariableEx +import com.intellij.psi.javadoc.PsiDocComment +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.idea.caches.lightClasses.LightMemberOriginForCompiledField +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 && fldParent == other.fldParent && fldDelegate == other.fldDelegate + + override fun hashCode(): Int = fldDelegate.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/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightMethodForDecompiledDeclaration.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightMethodForDecompiledDeclaration.kt new file mode 100644 index 00000000000..5acbebcaac0 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/decompiledDeclarations/KtLightMethodForDecompiledDeclaration.kt @@ -0,0 +1,104 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.caches.lightClasses.decompiledDeclarations + +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.asJava.checkIsMangled +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.idea.caches.lightClasses.LightMemberOriginForCompiledMethod +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 && funParent == other.funParent && funDelegate == other.funDelegate + + override fun hashCode(): Int = funDelegate.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 +} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt index 784f49f8fdf..38de1fbf9fb 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt @@ -182,7 +182,7 @@ class IDEKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupport if (facadeKtFile is KtClsFile) { val partClassFile = facadeKtFile.virtualFile.parent.findChild(partClassFileShortName) ?: return@mapNotNull null val javaClsClass = createClsJavaClassFromVirtualFile(facadeKtFile, partClassFile, null) ?: return@mapNotNull null - KtLightClassForDecompiledDeclaration(javaClsClass, null, facadeKtFile) + KtLightClassForDecompiledDeclaration(javaClsClass, javaClsClass.parent, facadeKtFile, null) } else { // TODO should we build light classes for parts from source? null @@ -291,7 +291,7 @@ class IDEKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupport correspondingClassOrObject = classOrObject ) ?: return null - return KtLightClassForDecompiledDeclaration(javaClsClass, classOrObject, file) + return KtLightClassForDecompiledDeclaration(javaClsClass, javaClsClass.parent, file, classOrObject) } private fun createClsJavaClassFromVirtualFile( diff --git a/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/KotlinBuiltInMemberFunction_verification.xml b/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/KotlinBuiltInMemberFunction_verification.xml index 3078779d022..9de7dc40482 100644 --- a/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/KotlinBuiltInMemberFunction_verification.xml +++ b/idea/testData/hierarchy/overrides/kotlinBuiltInMemberFunction/KotlinBuiltInMemberFunction_verification.xml @@ -1,22 +1,21 @@ - - - - - - - - + + + + + - - - + + + + + diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt index 28b98e9e940..1c7e20f87c8 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName import org.jetbrains.kotlin.j2k.ReferenceSearcher import org.jetbrains.kotlin.j2k.ast.Nullability import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.nj2k.symbols.* import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.* @@ -129,11 +130,15 @@ class JavaToJKTreeBuilder constructor( JKImportStatement(JKNameIdentifier(rawName)) else null } + + fun KtLightClassForDecompiledDeclaration.fqName(): FqName = + kotlinOrigin?.fqName ?: FqName(qualifiedName.orEmpty()) + val name = target.safeAs>()?.kotlinOrigin?.getKotlinFqName()?.asString() ?: target.safeAs()?.containingFile?.safeAs()?.packageFqName?.asString()?.let { "$it.*" } ?: target.safeAs()?.fqName?.parent()?.asString()?.let { "$it.*" } - ?: target.safeAs()?.fqName?.parent()?.asString()?.let { "$it.*" } + ?: target.safeAs()?.fqName()?.parent()?.asString()?.let { "$it.*" } ?: rawName return JKImportStatement(JKNameIdentifier(name)) diff --git a/tests/mute-platform.csv b/tests/mute-platform.csv index cedb9480397..f43f7c1cbda 100644 --- a/tests/mute-platform.csv +++ b/tests/mute-platform.csv @@ -1,6 +1,4 @@ Test key, Issue, State (optional: MUTE or FAIL), Status (optional: FLAKY) -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testClassObjects, ERROR: Access to tree elements not allowed.,, -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testUsingKotlinPackageDeclarations, ERROR: Access to tree elements not allowed.,, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryClassUsages, KT-34542, FAIL, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryNestedClassUsages, KT-34542, FAIL, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryObjectUsages, KT-34542, FAIL, diff --git a/tests/mute-platform.csv.192 b/tests/mute-platform.csv.192 index 4c67654a7c0..25f214430a7 100644 --- a/tests/mute-platform.csv.192 +++ b/tests/mute-platform.csv.192 @@ -1,6 +1,4 @@ Test key, Issue, State (optional: MUTE or FAIL), Status (optional: FLAKY) -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testClassObjects, ERROR: Access to tree elements not allowed.,, -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testUsingKotlinPackageDeclarations, ERROR: Access to tree elements not allowed.,, org.jetbrains.kotlin.idea.completion.test.JvmBasicCompletionTestGenerated.Common.StaticMembers.testJavaStaticMethodsFromImports, KT-32919,, org.jetbrains.kotlin.idea.completion.test.JvmBasicCompletionTestGenerated.Java.BoldOrGrayed.testNonPredictableSmartCast1, KT-32919,, org.jetbrains.kotlin.idea.completion.test.JvmBasicCompletionTestGenerated.Java.BoldOrGrayed.testNonPredictableSmartCast2, KT-32919,, diff --git a/tests/mute-platform.csv.201 b/tests/mute-platform.csv.201 index 0dfcec06f3f..3f9b26e489d 100644 --- a/tests/mute-platform.csv.201 +++ b/tests/mute-platform.csv.201 @@ -1,6 +1,4 @@ Test key, Issue, State (optional: MUTE or FAIL), Status (optional: FLAKY) -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testClassObjects, ERROR: Access to tree elements not allowed.,, -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testUsingKotlinPackageDeclarations, ERROR: Access to tree elements not allowed.,, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryClassUsages, KT-34542, FAIL, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryNestedClassUsages, KT-34542, FAIL, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryObjectUsages, KT-34542, FAIL, diff --git a/tests/mute-platform.csv.as36 b/tests/mute-platform.csv.as36 index c678c7b925b..bb5c0d9a24c 100644 --- a/tests/mute-platform.csv.as36 +++ b/tests/mute-platform.csv.as36 @@ -1,6 +1,4 @@ Test key, Issue, State (optional: MUTE or FAIL), Status (optional: FLAKY) -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testClassObjects, ERROR: Access to tree elements not allowed.,, -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testUsingKotlinPackageDeclarations, ERROR: Access to tree elements not allowed.,, org.jetbrains.kotlin.idea.codeInsight.gradle.GradleFacetImportTest.testAndroidGradleJsDetection, NPE during import,, org.jetbrains.kotlin.idea.codeInsight.gradle.GradleFacetImportTest.testKotlinAndroidPluginDetection, NPE during import,, org.jetbrains.kotlin.idea.codeInsight.gradle.GradleMigrateTest.testMigrateStdlib, Can't get migration information,, diff --git a/tests/mute-platform.csv.as40 b/tests/mute-platform.csv.as40 index 8344df9a06a..78af0be2851 100644 --- a/tests/mute-platform.csv.as40 +++ b/tests/mute-platform.csv.as40 @@ -1,6 +1,4 @@ Test key, Issue, State (optional: MUTE or FAIL), Status (optional: FLAKY) -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testClassObjects, ERROR: Access to tree elements not allowed.,, -org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testUsingKotlinPackageDeclarations, ERROR: Access to tree elements not allowed.,, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryClassUsages, KT-34542, FAIL, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryNestedClassUsages, KT-34542, FAIL, org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryObjectUsages, KT-34542, FAIL,