From f1a0d86f8741586727927d3e6623cad8fd3791b0 Mon Sep 17 00:00:00 2001 From: Michael Nedzelsky Date: Mon, 6 Apr 2015 11:21:47 +0300 Subject: [PATCH] JsMetaFileUtils: add some useful code, remove unnecessary parts --- .../decompiler/navigation/JsMetaFileUtils.kt | 147 ++++-------------- 1 file changed, 32 insertions(+), 115 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/JsMetaFileUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/JsMetaFileUtils.kt index f2079bea99e..3335beed7c4 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/JsMetaFileUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/JsMetaFileUtils.kt @@ -16,139 +16,56 @@ package org.jetbrains.kotlin.idea.decompiler.navigation -import com.intellij.ide.highlighter.JavaClassFileType -import com.intellij.openapi.fileTypes.FileType -import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.LibraryOrderEntry -import com.intellij.openapi.roots.ModuleRootManager -import com.intellij.openapi.roots.OrderRootType -import com.intellij.openapi.roots.ProjectRootModificationTracker -import com.intellij.openapi.roots.libraries.Library -import com.intellij.openapi.util.Key +import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.util.CachedValueProvider -import com.intellij.psi.util.CachedValuesManager -import com.intellij.testFramework.BinaryLightVirtualFile -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor -import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.idea.caches.resolve.LIBRARY_NAME_PREFIX -import org.jetbrains.kotlin.idea.framework.JsHeaderLibraryDetectionUtil -import org.jetbrains.kotlin.idea.project.ProjectStructureUtil +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.DescriptorUtils -import kotlin.platform.platformStatic +import org.jetbrains.kotlin.serialization.js.isDefaultPackageMetafile +import org.jetbrains.kotlin.serialization.js.isPackageClassFqName -fun getKotlinJavascriptLibraryWithMetadata(descriptor: DeclarationDescriptor, project: Project): Library? { - val containingPackageFragment = DescriptorUtils.getParentOfType(descriptor, javaClass()) - if (containingPackageFragment == null) return null +public object JsMetaFileUtils { - val module = DescriptorUtils.getContainingModule(descriptor) - assert(module is ModuleDescriptorImpl) + public fun getPackageFqName(file: VirtualFile): FqName = getPackageFqName(getRelativeToRootPath(file)) - return getKotlinJavascriptLibrary(module, project) -} + public fun getClassFqName(file: VirtualFile): FqName = getClassFqName(getRelativeToRootPath(file)) -fun getKotlinJavascriptLibrary(file: VirtualFile, project: Project): Library? { - val module = file.getUserData(JsMetaFileVirtualFileHolder.MODULE_DESCRIPTOR_KEY) - if (module == null) return null + public fun getClassId(file: VirtualFile): ClassId = getClassId(getRelativeToRootPath(file)) - return getKotlinJavascriptLibrary(module, project) -} + public fun isPackageHeader(file: VirtualFile): Boolean = isPackageHeader(getRelativeToRootPath(file)) -private fun Library.isWithoutSources(): Boolean = - !JsHeaderLibraryDetectionUtil.isJsHeaderLibraryWithSources(this.getFiles(OrderRootType.CLASSES).toList()) + public fun getModuleDirectory(file: VirtualFile): VirtualFile = + getRoot(file).findChild(getModuleName(getRelativeToRootPath(file)))!! -// getName() could return null for module level library -private fun Library.safeGetName(): String = this.getName() ?: "null" + private fun getRelativeToRootPath(file: VirtualFile): String = VfsUtilCore.getRelativePath(file, getRoot(file))!! -private fun getKotlinJavascriptLibrary(module: ModuleDescriptor, project: Project): Library? { - val libraryName = getLibraryName(module) - if (libraryName == null) return null - - val jsIdeaModules = ModuleManager.getInstance(project).getModules().filter { (ProjectStructureUtil.isJsKotlinModule(it)) } - for(ideaModule in jsIdeaModules) { - for(orderEntry in ModuleRootManager.getInstance(ideaModule).getOrderEntries()) { - if (orderEntry is LibraryOrderEntry) { - val library = orderEntry.getLibrary() - if (library != null && library.safeGetName() == libraryName && library.isWithoutSources()) { - return library - } - } - } + private fun getClassFqName(relPath: String): FqName { + val pathToFile = relPath.substringAfter(VfsUtilCore.VFS_SEPARATOR_CHAR) + return FqName(pathToFile.substringBeforeLast('.').replace(VfsUtilCore.VFS_SEPARATOR_CHAR, '.')) } - return null -} + private fun getClassId(relPath: String): ClassId { + val classFqName = getClassFqName(relPath) + val packageFqName = getPackageFqName(relPath) -private fun getLibraryName(module: ModuleDescriptor): String? { - var moduleName = module.getName().asString() - moduleName = moduleName.substring(1, moduleName.length() - 1) - - if (!moduleName.startsWith(LIBRARY_NAME_PREFIX)) return null - - return moduleName.substring(LIBRARY_NAME_PREFIX.length()) -} - - -class JsMetaFileVirtualFileHolder private(val myProject: Project) { - companion object { - public val MODULE_DESCRIPTOR_KEY: Key = Key.create("MODULE_DESCRIPTOR") - public val PACKAGE_FQNAME_KEY: Key = Key.create("PACKAGE_FQNAME_KEY") - private val JS_META_FILE_HOLDER_KEY: Key = Key.create("JS_META_FILE_HOLDER_KEY") - - platformStatic - public fun getInstance(project: Project): JsMetaFileVirtualFileHolder { - var holder = project.getUserData(JS_META_FILE_HOLDER_KEY) - - if (holder == null) { - holder = JsMetaFileVirtualFileHolder(project) - project.putUserData(JS_META_FILE_HOLDER_KEY, holder) - } - - return holder - } + val name = classFqName.shortName().asString().substringBeforeLast('.') + return ClassId(packageFqName, FqName(name), false) } - private val cachedFileMap = CachedValuesManager.getManager(myProject).createCachedValue( { - CachedValueProvider.Result(hashMapOf(), ProjectRootModificationTracker.getInstance(myProject)) - }, false) + private fun getPackageFqName(relPath: String): FqName { + val pathToFile = relPath.substringAfter(VfsUtilCore.VFS_SEPARATOR_CHAR) + if (isDefaultPackageMetafile(pathToFile)) return FqName.ROOT - fun getFile(descriptor: DeclarationDescriptor): VirtualFile? { - val containingPackageFragment = DescriptorUtils.getParentOfType(descriptor, javaClass()) - if (containingPackageFragment == null) return null - - val packageName = DescriptorUtils.getFqName(containingPackageFragment).asString() - - val module = DescriptorUtils.getContainingModule(descriptor) - assert(module is ModuleDescriptorImpl) - - var moduleName = module.getName().asString() - moduleName = moduleName.substring(1, moduleName.length() - 1) - if (moduleName.startsWith("library ")) { - moduleName = moduleName.substring(8) - } - - val fileName = "${moduleName}/${packageName}.meta" - val fileMap = cachedFileMap.getValue() - - var result = fileMap[fileName] - - if (result == null) { - result = JsMetaFileBinaryLightVirtualFile(fileName) - fileMap[fileName] = result!! - } - - result?.putUserData(MODULE_DESCRIPTOR_KEY, module as ModuleDescriptorImpl) - result?.putUserData(PACKAGE_FQNAME_KEY, FqName(packageName)) - - return result + val name = pathToFile.substringBeforeLast(VfsUtilCore.VFS_SEPARATOR_CHAR) + return FqName(name.replace(VfsUtilCore.VFS_SEPARATOR_CHAR, '.')) } - private inner class JsMetaFileBinaryLightVirtualFile(name: String) : BinaryLightVirtualFile(name) { - override fun getFileType(): FileType = JavaClassFileType.INSTANCE + private fun getModuleName(relPath: String): String = relPath.substringBefore(VfsUtilCore.VFS_SEPARATOR_CHAR) + + private fun isPackageHeader(relPath: String): Boolean { + val classFqName = JsMetaFileUtils.getClassFqName(relPath) + return classFqName.isPackageClassFqName() } + + private fun getRoot(file: VirtualFile): VirtualFile = if (file.getParent() == null) file else getRoot(file.getParent()) }