diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt index 0f29456b429..626abf15b5c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt @@ -18,7 +18,9 @@ package org.jetbrains.kotlin.idea.caches.resolve.lightClasses import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project +import com.intellij.psi.search.EverythingGlobalScope import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.stubs.StubIndex import org.jetbrains.kotlin.analyzer.LanguageSettingsProvider import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext import org.jetbrains.kotlin.config.JvmTarget @@ -39,6 +41,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.IDELightClassConstr import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.IDELightClassConstructionContext.Mode.LIGHT import org.jetbrains.kotlin.idea.project.IdeaEnvironment import org.jetbrains.kotlin.idea.project.ResolveElementCache +import org.jetbrains.kotlin.idea.stubindex.KotlinOverridableInternalMembersShortNameIndex import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens @@ -140,14 +143,22 @@ object IDELightClassContexts { private fun isDummyResolveApplicable(classOrObject: KtClassOrObject): Boolean { if (classOrObject.hasLightClassMatchingErrors) return false - val hasDelegatedMembers = classOrObject.superTypeListEntries.any { it is KtDelegatedSuperTypeEntry } - val dataClassWithGeneratedMembersOverridden = - classOrObject.hasModifier(KtTokens.DATA_KEYWORD) && - classOrObject.declarations.filterIsInstance().any { - isGeneratedForDataClass(it.nameAsSafeName) - } - return !hasDelegatedMembers && !dataClassWithGeneratedMembersOverridden - && classOrObject.declarations.filterIsInstance().all { isDummyResolveApplicable(it) } + if (hasDelegatedSupertypes(classOrObject)) return false + + if (isDataClassWithGeneratedMembersOverridden(classOrObject)) return false + + if (hasMembersOverridingInternalMembers(classOrObject)) return false + + return classOrObject.declarations.filterIsInstance().all { isDummyResolveApplicable(it) } + } + + private fun hasDelegatedSupertypes(classOrObject: KtClassOrObject) = classOrObject.superTypeListEntries.any { it is KtDelegatedSuperTypeEntry } + + private fun isDataClassWithGeneratedMembersOverridden(classOrObject: KtClassOrObject): Boolean { + return classOrObject.hasModifier(KtTokens.DATA_KEYWORD) && + classOrObject.declarations.filterIsInstance().any { + isGeneratedForDataClass(it.nameAsSafeName) + } } private fun isGeneratedForDataClass(name: Name): Boolean { @@ -159,6 +170,30 @@ object IDELightClassContexts { DataClassDescriptorResolver.isComponentLike(name) } + private fun hasMembersOverridingInternalMembers(classOrObject: KtClassOrObject): Boolean { + return classOrObject.declarations.filterIsInstance().any { + possiblyOverridesInternalMember(it) + } + } + + private fun possiblyOverridesInternalMember(declaration: KtCallableDeclaration): Boolean { + if (!declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false + + return declaration.name?.let { anyInternalMembersWithThisName(it, declaration.project) } ?: false + } + + private fun anyInternalMembersWithThisName(name: String, project: Project): Boolean { + var result = false + StubIndex.getInstance().processElements( + KotlinOverridableInternalMembersShortNameIndex.Instance.key, name, project, + EverythingGlobalScope(project), KtCallableDeclaration::class.java + ) { + result = true + false // stop processing at first matching result + } + return result + } + fun lightContextForFacade(files: List): LightClassConstructionContext { val representativeFile = files.first() val resolveSession = setupAdHocResolve(representativeFile.project, representativeFile.getResolutionFacade().moduleDescriptor, files) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/LazyLightClassDataHolder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/LazyLightClassDataHolder.kt index 047bb2e413a..efe50a02e69 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/LazyLightClassDataHolder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/LazyLightClassDataHolder.kt @@ -16,14 +16,11 @@ package org.jetbrains.kotlin.idea.caches.resolve.lightClasses -import com.intellij.openapi.project.Project import com.intellij.openapi.util.Key import com.intellij.psi.PsiClass import com.intellij.psi.PsiMember import com.intellij.psi.PsiMethod import com.intellij.psi.impl.java.stubs.PsiJavaFileStub -import com.intellij.psi.search.EverythingGlobalScope -import com.intellij.psi.stubs.StubIndex import org.jetbrains.kotlin.asJava.LightClassBuilder import org.jetbrains.kotlin.asJava.builder.* import org.jetbrains.kotlin.asJava.classes.KtLightClass @@ -32,11 +29,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl -import org.jetbrains.kotlin.idea.stubindex.KotlinOverridableInternalMembersShortNameIndex -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.NotNullableUserDataProperty typealias ExactLightClassContextProvider = () -> LightClassConstructionContext @@ -94,10 +87,6 @@ sealed class LazyLightClassDataHolder( return dummyDelegate!!.fields.map { dummyField -> val fieldOrigin = KtLightFieldImpl.getOrigin(dummyField)!! - if (shouldRollbackOptimization(fieldOrigin)) { - return@getOwnFields KtLightFieldImpl.fromClsFields(clsDelegate, containingClass) - } - val fieldName = dummyField.name!! KtLightFieldImpl.lazy(dummyField, fieldOrigin, containingClass) { clsDelegate.findFieldByName(fieldName, false).assertMatches(dummyField, containingClass) @@ -111,10 +100,6 @@ sealed class LazyLightClassDataHolder( return dummyDelegate!!.methods.map { dummyMethod -> val methodOrigin = KtLightMethodImpl.getOrigin(dummyMethod) - if (shouldRollbackOptimization(methodOrigin)) { - return@getOwnMethods KtLightMethodImpl.fromClsMethods(clsDelegate, containingClass) - } - KtLightMethodImpl.lazy(dummyMethod, containingClass, methodOrigin) { val dummyIndex = dummyMethod.memberIndex!! @@ -146,28 +131,6 @@ sealed class LazyLightClassDataHolder( } } -private fun shouldRollbackOptimization(origin: LightMemberOriginForDeclaration?): Boolean { - val kotlinDeclaration = origin?.originalElement as? KtNamedDeclaration ?: return false - - if (!kotlinDeclaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false - - val possiblyOverridesInternalMember = kotlinDeclaration.name?.let { anyInternalMembersWithThisName(it, kotlinDeclaration.project) } ?: false - return possiblyOverridesInternalMember -} - - -private fun anyInternalMembersWithThisName(name: String, project: Project): Boolean { - var result = false - StubIndex.getInstance().processElements( - KotlinOverridableInternalMembersShortNameIndex.Instance.key, name, project, - EverythingGlobalScope(project), KtCallableDeclaration::class.java - ) { - result = true - false // stop processing at first matching result - } - return result -} - private sealed class LazyLightClassMemberMatchingError(message: String, containingClass: KtLightClass) : AssertionError(message) {