LazyLightClassDataHolder: move internal members check to IDELightClassContexts#isDummyResolveApplicable

This commit is contained in:
Pavel V. Talanov
2017-04-28 15:32:22 +03:00
parent 0571c62943
commit 178e59a6e8
2 changed files with 43 additions and 45 deletions
@@ -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<KtFunction>().any {
isGeneratedForDataClass(it.nameAsSafeName)
}
return !hasDelegatedMembers && !dataClassWithGeneratedMembersOverridden
&& classOrObject.declarations.filterIsInstance<KtClassOrObject>().all { isDummyResolveApplicable(it) }
if (hasDelegatedSupertypes(classOrObject)) return false
if (isDataClassWithGeneratedMembersOverridden(classOrObject)) return false
if (hasMembersOverridingInternalMembers(classOrObject)) return false
return classOrObject.declarations.filterIsInstance<KtClassOrObject>().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<KtFunction>().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<KtCallableDeclaration>().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<KtFile>): LightClassConstructionContext {
val representativeFile = files.first()
val resolveSession = setupAdHocResolve(representativeFile.project, representativeFile.getResolutionFacade().moduleDescriptor, files)
@@ -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) {