From 9b8540543f3974e7fb30ea293d8d572a1ff97ca0 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Mon, 7 Sep 2015 17:24:06 +0300 Subject: [PATCH] Fix generation of light classes for package facade from binaries Refactor code a bit --- .../resolve/IDELightClassGenerationSupport.kt | 53 ++++++++----------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index a9dfdbee964..db971e2cb55 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -45,6 +45,7 @@ import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.load.kotlin.PackageClassUtils import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* @@ -57,7 +58,6 @@ import java.io.IOException import java.util.* public class IDELightClassGenerationSupport(private val project: Project) : LightClassGenerationSupport() { - private val scopeFileComparator = JavaElementFinder.byClasspathComparator(GlobalSearchScope.allScope(project)) private val psiManager: PsiManager = PsiManager.getInstance(project) @@ -141,17 +141,22 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh override fun getPackageClasses(packageFqName: FqName, scope: GlobalSearchScope): Collection { val result = ArrayList() - val packageClassesInfos = findPackageClassesInfos(packageFqName, scope) - for (info in packageClassesInfos) { - val files = PackagePartClassUtils.getFilesWithCallables(info.files) + val filesWithCallables = PackagePartClassUtils.getFilesWithCallables(findFilesForPackage(packageFqName, scope)) + val filesByModule = filesWithCallables.groupBy { it.getModuleInfo() } + for ((moduleInfo, files) in filesByModule) { if (files.isEmpty()) continue - val moduleInfo = info.moduleInfo if (moduleInfo is ModuleSourceInfo) { result.addAll(getLightClassesForPackageFacadeWithSources(packageFqName, files, moduleInfo)) } else { - result.addAll(getLightClassesForDecompiledFacadeFiles(files)) + val packageClassName = PackageClassUtils.getPackageClassName(packageFqName) + val virtualFileForPackageClass = files.asSequence().map { + it.virtualFile?.parent?.findChild("$packageClassName.class") + }.firstOrNull { it != null } ?: continue + + val clsClassFromPackageClass = createClsJavaClassFromVirtualFile(files.first(), virtualFileForPackageClass, null) ?: continue + result.add(KotlinLightClassForDecompiledDeclaration(clsClassFromPackageClass, null)) } } return result @@ -184,12 +189,13 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection { val result = ArrayList() - val facadeClassesInfos = findFacadeClassesInfos(facadeFqName, scope) - for (info in facadeClassesInfos) { - val files = PackagePartClassUtils.getFilesWithCallables(info.files) + val filesByModule = PackagePartClassUtils.getFilesWithCallables(findFilesForFacade(facadeFqName, scope)).groupBy { + it.getModuleInfo() + } + + for ((moduleInfo, files) in filesByModule) { if (files.isEmpty()) continue - val moduleInfo = info.moduleInfo if (moduleInfo is ModuleSourceInfo) { result.addAll(getLightClassesForStaticFacadeWithSources(facadeFqName, files, moduleInfo)) } @@ -203,7 +209,8 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh private fun getLightClassesForStaticFacadeWithSources( facadeFqName: FqName, facadeFiles: List, - moduleInfo: IdeaModuleInfo): List { + moduleInfo: IdeaModuleInfo + ): List { val lightClassForFacade = KotlinLightClassForFacade.createForFacade( psiManager, facadeFqName, moduleInfo.contentScope(), facadeFiles) return getLightClassesForFacadeWithFiles(lightClassForFacade, facadeFiles) @@ -213,11 +220,6 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh return StaticFacadeIndexUtil.findFilesForStaticFacade(facadeFqName, kotlinSourcesAndLibraries(scope, project), project) } - private fun findFacadeClassesInfos(facadeFqName: FqName, scope: GlobalSearchScope): List { - val facadeFiles = findFilesForFacade(facadeFqName, scope) - return groupFilesIntoFacadeLightClassesByModuleInfo(facadeFiles) - } - override fun resolveClassToDescriptor(classOrObject: JetClassOrObject): ClassDescriptor? { try { return classOrObject.resolveToDescriptor() as ClassDescriptor @@ -227,13 +229,6 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh } } - private fun findPackageClassesInfos(fqName: FqName, wholeScope: GlobalSearchScope): List { - val allFiles = findFilesForPackage(fqName, wholeScope) - return groupFilesIntoFacadeLightClassesByModuleInfo(allFiles) - } - - private class KotlinLightFacadeClassInfo(public val files: Collection, public val moduleInfo: IdeaModuleInfo) - private class CachedJavaStub(public var modificationStamp: Long, public var javaFileStub: PsiJavaFileStubImpl) companion object { @@ -321,12 +316,6 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh return getClassRelativeName(parent).child(name) } - private fun groupFilesIntoFacadeLightClassesByModuleInfo(facadeFiles: Collection): List { - val filesByInfo = facadeFiles.groupBy { it.getModuleInfo() } - - return filesByInfo.map { KotlinLightFacadeClassInfo(it.value, it.key) } - } - private fun getLightClassesForDecompiledFacadeFiles(filesWithCallables: List): List { return filesWithCallables.filter { it.isCompiled }.map { createLightClassForDecompiledKotlinFile(it) }.filterNotNull() } @@ -343,7 +332,8 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh private fun createClsJavaClassFromVirtualFile( decompiledKotlinFile: JetFile, virtualFile: VirtualFile, - decompiledClassOrObject: JetClassOrObject?): ClsClassImpl? { + decompiledClassOrObject: JetClassOrObject? + ): ClsClassImpl? { val javaFileStub = getOrCreateJavaFileStub(decompiledKotlinFile, virtualFile) ?: return null val manager = PsiManager.getInstance(decompiledKotlinFile.project) val fakeFile = object : ClsFileImpl(ClassFileViewProvider(manager, virtualFile)) { @@ -371,7 +361,8 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh private fun getOrCreateJavaFileStub( decompiledKotlinFile: JetFile, - virtualFile: VirtualFile): PsiJavaFileStubImpl? { + virtualFile: VirtualFile + ): PsiJavaFileStubImpl? { val cachedJavaStub = decompiledKotlinFile.getUserData(cachedJavaStubKey) val fileModificationStamp = virtualFile.modificationStamp if (cachedJavaStub != null && cachedJavaStub.modificationStamp == fileModificationStamp) {