From 9a2442bba688e97527805028799578424aecd857 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Thu, 3 Dec 2015 16:20:11 +0300 Subject: [PATCH] Decompiler, refactor: reduce the number of classes needed to define a decompiler --- ...kt => KotlinDecompiledFileViewProvider.kt} | 11 ++- ...ompiledFileBase.kt => KtDecompiledFile.kt} | 9 +- .../classFile/KotlinClassFileDecompiler.kt | 89 +++++++++++++++++- .../classFile/KotlinClassFileViewProvider.kt | 46 ---------- .../idea/decompiler/classFile/KtClsFile.kt | 91 ------------------- .../KotlinJavaScriptMetaFileDecompiler.java | 46 ---------- ... => KotlinJavaScriptMetaFileDecompiler.kt} | 34 ++++++- .../KotlinJavascriptMetaFileViewProvider.kt | 36 -------- .../navigation/DecompiledNavigationUtils.java | 6 +- .../jetbrains/kotlin/idea/test/testUtils.kt | 6 +- ...bstractDecompiledTextFromJsMetadataTest.kt | 4 +- 11 files changed, 137 insertions(+), 241 deletions(-) rename idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/{KotlinDecompiledFileViewProviderBase.kt => KotlinDecompiledFileViewProvider.kt} (83%) rename idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/{KtDecompiledFileBase.kt => KtDecompiledFile.kt} (91%) delete mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClassFileViewProvider.kt delete mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KtClsFile.kt delete mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.java rename idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/{KotlinJavascriptMetaFile.kt => KotlinJavaScriptMetaFileDecompiler.kt} (66%) delete mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavascriptMetaFileViewProvider.kt diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinDecompiledFileViewProviderBase.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinDecompiledFileViewProvider.kt similarity index 83% rename from idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinDecompiledFileViewProviderBase.kt rename to idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinDecompiledFileViewProvider.kt index 3b55177a35f..11fa18472a4 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinDecompiledFileViewProviderBase.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinDecompiledFileViewProvider.kt @@ -28,10 +28,12 @@ import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue -abstract class KotlinDecompiledFileViewProviderBase( +class KotlinDecompiledFileViewProvider( manager: PsiManager, file: VirtualFile, - physical: Boolean) : SingleRootFileViewProvider(manager, file, physical, KotlinLanguage.INSTANCE) { + physical: Boolean, + private val factory: (KotlinDecompiledFileViewProvider) -> KtDecompiledFile? +) : SingleRootFileViewProvider(manager, file, physical, KotlinLanguage.INSTANCE) { val content : LockedClearableLazyValue = LockedClearableLazyValue(Any()) { val psiFile = createFile(manager.getProject(), file, KotlinFileType.INSTANCE) val text = psiFile?.getText() ?: "" @@ -48,9 +50,10 @@ abstract class KotlinDecompiledFileViewProviderBase( } override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? { - // Workaround for KT-8344 - return super.createFile(project, file, fileType) + return factory(this) } + override fun createCopy(copy: VirtualFile) = KotlinDecompiledFileViewProvider(getManager(), copy, false, factory) + override fun getContents() = content.get() } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KtDecompiledFileBase.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KtDecompiledFile.kt similarity index 91% rename from idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KtDecompiledFileBase.kt rename to idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KtDecompiledFile.kt index da24e997b43..4aea6dd8caf 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KtDecompiledFileBase.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KtDecompiledFile.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.decompiler import com.intellij.openapi.util.TextRange +import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.descriptors.ConstructorDescriptor @@ -30,11 +31,13 @@ import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue -public abstract class KtDecompiledFileBase(val provider: KotlinDecompiledFileViewProviderBase) : KtFile(provider, true) { - abstract fun buildDecompiledText(): DecompiledText +open class KtDecompiledFile( + private val provider: KotlinDecompiledFileViewProvider, + buildDecompiledText: (VirtualFile) -> DecompiledText +) : KtFile(provider, true) { private val decompiledText = LockedClearableLazyValue(Any()) { - buildDecompiledText() + buildDecompiledText(provider.virtualFile) } public fun getDeclarationForDescriptor(descriptor: DeclarationDescriptor): KtDeclaration? { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClassFileDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClassFileDecompiler.kt index 55ed1494817..76a9f51a9a8 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClassFileDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClassFileDecompiler.kt @@ -16,9 +16,27 @@ package org.jetbrains.kotlin.idea.decompiler.classFile +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.roots.FileIndexFacade import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiManager import com.intellij.psi.compiled.ClassFileDecompilers +import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProvider +import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile +import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText +import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolverForDecompiler +import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache +import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind +import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind +import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassKind +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.renderer.DescriptorRendererModifier +import org.jetbrains.kotlin.renderer.ExcludedTypeAnnotations +import org.jetbrains.kotlin.types.flexibility +import org.jetbrains.kotlin.types.isFlexible +import java.util.* public class KotlinClassFileDecompiler : ClassFileDecompilers.Full() { private val stubBuilder = KotlinClsStubBuilder() @@ -27,6 +45,73 @@ public class KotlinClassFileDecompiler : ClassFileDecompilers.Full() { override fun getStubBuilder() = stubBuilder - override fun createFileViewProvider(file: VirtualFile, manager: PsiManager, physical: Boolean) - = KotlinClassFileViewProvider(manager, file, physical, isKotlinInternalCompiledFile(file)) + override fun createFileViewProvider(file: VirtualFile, manager: PsiManager, physical: Boolean): KotlinDecompiledFileViewProvider { + val project = manager.project + return KotlinDecompiledFileViewProvider(manager, file, physical) { provider -> + val virtualFile = provider.virtualFile + val fileIndex = ServiceManager.getService(project, FileIndexFacade::class.java) + if (!fileIndex.isInLibraryClasses(virtualFile) && fileIndex.isInSource(virtualFile)) { + null + } + else if (isKotlinInternalCompiledFile(virtualFile)) { + null + } + else { + KtClsFile(provider) + } + } + } +} + +class KtClsFile(provider: KotlinDecompiledFileViewProvider) : KtDecompiledFile(provider, { file -> buildDecompiledTextForClassFile(file) }) + +private val descriptorRendererForClassFileDecompiler = DescriptorRenderer.withOptions { + withDefinedIn = false + classWithPrimaryConstructor = true + typeNormalizer = { type -> if (type.isFlexible()) type.flexibility().lowerBound else type } + secondaryConstructorsAsPrimary = false + modifiers = DescriptorRendererModifier.ALL + excludedTypeAnnotationClasses = ExcludedTypeAnnotations.annotationsForNullabilityAndMutability +} + +private val FILE_ABI_VERSION_MARKER: String = "FILE_ABI" +private val CURRENT_ABI_VERSION_MARKER: String = "CURRENT_ABI" + +public val INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT: String = "// This class file was compiled with different version of Kotlin compiler and can't be decompiled." +public val INCOMPATIBLE_ABI_VERSION_COMMENT: String = + "$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" + + "//\n" + + "// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" + + "// File ABI version is $FILE_ABI_VERSION_MARKER" + +public fun buildDecompiledTextForClassFile( + classFile: VirtualFile, + resolver: ResolverForDecompiler = DeserializerForClassfileDecompiler(classFile) +): DecompiledText { + val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile) + assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile } + val classId = kotlinClass!!.getClassId() + val classHeader = kotlinClass.getClassHeader() + val packageFqName = classId.getPackageFqName() + + return when { + !classHeader.isCompatibleAbiVersion -> { + DecompiledText( + INCOMPATIBLE_ABI_VERSION_COMMENT + .replace(CURRENT_ABI_VERSION_MARKER, JvmAbi.VERSION.toString()) + .replace(FILE_ABI_VERSION_MARKER, classHeader.version.toString()), + mapOf()) + } + classHeader.isCompatibleFileFacadeKind() -> + buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInFacade(classId.asSingleFqName())), descriptorRendererForClassFileDecompiler) + classHeader.isCompatibleClassKind() -> + buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), descriptorRendererForClassFileDecompiler) + classHeader.isCompatibleMultifileClassKind() -> { + val partClasses = findMultifileClassParts(classFile, kotlinClass) + val partMembers = partClasses.flatMap { partClass -> resolver.resolveDeclarationsInFacade(partClass.classId.asSingleFqName()) } + buildDecompiledText(packageFqName, partMembers, descriptorRendererForClassFileDecompiler) + } + else -> + throw UnsupportedOperationException("Unknown header kind: ${classHeader.kind} ${classHeader.isCompatibleAbiVersion}") + } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClassFileViewProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClassFileViewProvider.kt deleted file mode 100644 index 1b80dedaffa..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClassFileViewProvider.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.decompiler.classFile - -import com.intellij.openapi.components.ServiceManager -import com.intellij.openapi.fileTypes.FileType -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.FileIndexFacade -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiFile -import com.intellij.psi.PsiManager -import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProviderBase - -public class KotlinClassFileViewProvider( - manager: PsiManager, - file: VirtualFile, - physical: Boolean, - val isInternal: Boolean) : KotlinDecompiledFileViewProviderBase(manager, file, physical) { - - override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? { - val fileIndex = ServiceManager.getService(project, javaClass()) - if (!fileIndex.isInLibraryClasses(file) && fileIndex.isInSource(file)) { - return null - } - - if (isInternal) return null - - return KtClsFile(this) - } - - override fun createCopy(copy: VirtualFile) = KotlinClassFileViewProvider(getManager(), copy, false, isInternal) -} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KtClsFile.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KtClsFile.kt deleted file mode 100644 index 85cd0bf3c44..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KtClsFile.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.decompiler.classFile - -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProviderBase -import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFileBase -import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText -import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolverForDecompiler -import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText -import org.jetbrains.kotlin.load.java.JvmAbi -import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind -import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassKind -import org.jetbrains.kotlin.renderer.DescriptorRenderer -import org.jetbrains.kotlin.renderer.DescriptorRendererModifier -import org.jetbrains.kotlin.renderer.ExcludedTypeAnnotations -import org.jetbrains.kotlin.types.flexibility -import org.jetbrains.kotlin.types.isFlexible -import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue -import java.util.* - -public class KtClsFile(provider: KotlinDecompiledFileViewProviderBase) : KtDecompiledFileBase(provider) { - override fun buildDecompiledText() = buildDecompiledTextForClassFile(virtualFile) -} - -private val descriptorRendererForClassFileDecompiler = DescriptorRenderer.withOptions { - withDefinedIn = false - classWithPrimaryConstructor = true - typeNormalizer = { type -> if (type.isFlexible()) type.flexibility().lowerBound else type } - secondaryConstructorsAsPrimary = false - modifiers = DescriptorRendererModifier.ALL - excludedTypeAnnotationClasses = ExcludedTypeAnnotations.annotationsForNullabilityAndMutability -} - -private val FILE_ABI_VERSION_MARKER: String = "FILE_ABI" -private val CURRENT_ABI_VERSION_MARKER: String = "CURRENT_ABI" - -public val INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT: String = "// This class file was compiled with different version of Kotlin compiler and can't be decompiled." -public val INCOMPATIBLE_ABI_VERSION_COMMENT: String = - "$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" + - "//\n" + - "// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" + - "// File ABI version is $FILE_ABI_VERSION_MARKER" - -public fun buildDecompiledTextForClassFile( - classFile: VirtualFile, - resolver: ResolverForDecompiler = DeserializerForClassfileDecompiler(classFile) -): DecompiledText { - val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile) - assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile } - val classId = kotlinClass!!.getClassId() - val classHeader = kotlinClass.getClassHeader() - val packageFqName = classId.getPackageFqName() - - return when { - !classHeader.isCompatibleAbiVersion -> { - DecompiledText( - INCOMPATIBLE_ABI_VERSION_COMMENT - .replace(CURRENT_ABI_VERSION_MARKER, JvmAbi.VERSION.toString()) - .replace(FILE_ABI_VERSION_MARKER, classHeader.version.toString()), - mapOf()) - } - classHeader.isCompatibleFileFacadeKind() -> - buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInFacade(classId.asSingleFqName())), descriptorRendererForClassFileDecompiler) - classHeader.isCompatibleClassKind() -> - buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), descriptorRendererForClassFileDecompiler) - classHeader.isCompatibleMultifileClassKind() -> { - val partClasses = findMultifileClassParts(classFile, kotlinClass) - val partMembers = partClasses.flatMap { partClass -> resolver.resolveDeclarationsInFacade(partClass.classId.asSingleFqName()) } - buildDecompiledText(packageFqName, partMembers, descriptorRendererForClassFileDecompiler) - } - else -> - throw UnsupportedOperationException("Unknown header kind: ${classHeader.kind} ${classHeader.isCompatibleAbiVersion}") - } -} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.java deleted file mode 100644 index c1ba5e77497..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.decompiler.js; - -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.FileViewProvider; -import com.intellij.psi.PsiManager; -import com.intellij.psi.compiled.ClassFileDecompilers; -import com.intellij.psi.compiled.ClsStubBuilder; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil; - -public class KotlinJavaScriptMetaFileDecompiler extends ClassFileDecompilers.Full { - private final ClsStubBuilder stubBuilder = new KotlinJavaScriptStubBuilder(); - - @Override - public boolean accepts(@NotNull VirtualFile file) { - return file.getName().endsWith("." + KotlinJavascriptSerializationUtil.CLASS_METADATA_FILE_EXTENSION); - } - - @NotNull - @Override - public ClsStubBuilder getStubBuilder() { - return stubBuilder; - } - - @NotNull - @Override - public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, @NotNull PsiManager manager, boolean physical) { - return new KotlinJavascriptMetaFileViewProvider(manager, file, physical, JsMetaFileUtils.INSTANCE.isKotlinJavaScriptInternalCompiledFile(file)); - } -} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavascriptMetaFile.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.kt similarity index 66% rename from idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavascriptMetaFile.kt rename to idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.kt index 99e45cd7cfe..f14a30a17e3 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavascriptMetaFile.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.kt @@ -17,7 +17,12 @@ package org.jetbrains.kotlin.idea.decompiler.js import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFileBase +import com.intellij.psi.FileViewProvider +import com.intellij.psi.PsiManager +import com.intellij.psi.compiled.ClassFileDecompilers +import com.intellij.psi.compiled.ClsStubBuilder +import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProvider +import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolverForDecompiler import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText @@ -26,11 +31,30 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererModifier import org.jetbrains.kotlin.renderer.ExcludedTypeAnnotations -import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue +import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import java.util.* -public class KotlinJavascriptMetaFile(provider: KotlinJavascriptMetaFileViewProvider) : KtDecompiledFileBase(provider) { - override fun buildDecompiledText() = buildDecompiledTextFromJsMetadata(virtualFile) +class KotlinJavaScriptMetaFileDecompiler : ClassFileDecompilers.Full() { + private val stubBuilder = KotlinJavaScriptStubBuilder() + + override fun accepts(file: VirtualFile): Boolean { + return file.name.endsWith("." + KotlinJavascriptSerializationUtil.CLASS_METADATA_FILE_EXTENSION) + } + + override fun getStubBuilder(): ClsStubBuilder { + return stubBuilder + } + + override fun createFileViewProvider(file: VirtualFile, manager: PsiManager, physical: Boolean): FileViewProvider { + return KotlinDecompiledFileViewProvider(manager, file, physical) { provider -> + if (JsMetaFileUtils.isKotlinJavaScriptInternalCompiledFile(file)) { + null + } + else { + KtDecompiledFile(provider) { file -> buildDecompiledTextFromJsMetadata(file) } + } + } + } } private val descriptorRendererForKotlinJavascriptDecompiler = DescriptorRenderer.withOptions { @@ -60,4 +84,4 @@ public fun buildDecompiledTextFromJsMetadata( } private fun resolveDeclarationsInPackage(packageFqName: FqName, resolver: ResolverForDecompiler) = - ArrayList(resolver.resolveDeclarationsInFacade(OldPackageFacadeClassUtils.getPackageClassFqName(packageFqName))) + ArrayList(resolver.resolveDeclarationsInFacade(OldPackageFacadeClassUtils.getPackageClassFqName(packageFqName))) \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavascriptMetaFileViewProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavascriptMetaFileViewProvider.kt deleted file mode 100644 index 7da4f2f1d8f..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavascriptMetaFileViewProvider.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.decompiler.js - -import com.intellij.openapi.fileTypes.FileType -import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiManager -import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProviderBase - -public class KotlinJavascriptMetaFileViewProvider ( - manager: PsiManager, - val file: VirtualFile, - physical: Boolean, - val isInternal: Boolean) : KotlinDecompiledFileViewProviderBase(manager, file, physical) { - - //TODO: check index that file is library file, as in ClassFileViewProvider - override fun createFile(project: Project, file: VirtualFile, fileType: FileType) = - if (!isInternal) KotlinJavascriptMetaFile(this) else null - - override fun createCopy(copy: VirtualFile) = KotlinJavascriptMetaFileViewProvider(getManager(), copy, false, isInternal) -} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.java index 46173caa636..476435dd79d 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.java @@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; -import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFileBase; +import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile; import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope; import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil; import org.jetbrains.kotlin.idea.vfilefinder.JsVirtualFileFinderFactory; @@ -62,11 +62,11 @@ public final class DecompiledNavigationUtils { if (virtualFile == null) return null; PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); - if (!(psiFile instanceof KtDecompiledFileBase)) { + if (!(psiFile instanceof KtDecompiledFile)) { return null; } - return ((KtDecompiledFileBase) psiFile).getDeclarationForDescriptor(referencedDescriptor); + return ((KtDecompiledFile) psiFile).getDeclarationForDescriptor(referencedDescriptor); } private static boolean isLocal(DeclarationDescriptor descriptor) { diff --git a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/testUtils.kt b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/testUtils.kt index dc76aebf515..f2a226eb0df 100644 --- a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/testUtils.kt +++ b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/testUtils.kt @@ -32,7 +32,7 @@ import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.idea.caches.resolve.LibraryModificationTracker import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult -import org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClassFileViewProvider +import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProvider import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver import org.jetbrains.kotlin.psi.KtFile @@ -87,10 +87,10 @@ public fun closeAndDeleteProject(): Unit = public fun unInvalidateBuiltinsAndStdLib(project: Project, runnable: RunnableWithException) { val builtInsSources = BuiltInsReferenceResolver.getInstance(project).builtInsSources!! - val stdLibViewProviders = HashSet() + val stdLibViewProviders = HashSet() val vFileToViewProviderMap = ((PsiManager.getInstance(project) as PsiManagerEx).fileManager as FileManagerImpl).vFileToViewProviderMap for ((file, viewProvider) in vFileToViewProviderMap) { - if (file.isStdLibFile && viewProvider is KotlinClassFileViewProvider) { + if (file.isStdLibFile && viewProvider is KotlinDecompiledFileViewProvider) { stdLibViewProviders.add(viewProvider) } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/AbstractDecompiledTextFromJsMetadataTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/AbstractDecompiledTextFromJsMetadataTest.kt index 0904721a363..742cc12530d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/AbstractDecompiledTextFromJsMetadataTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/AbstractDecompiledTextFromJsMetadataTest.kt @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.decompiler.textBuilder import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiFile -import org.jetbrains.kotlin.idea.decompiler.js.KotlinJavascriptMetaFile +import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile import org.jetbrains.kotlin.idea.decompiler.navigation.NavigateToDecompiledLibraryTest import org.jetbrains.kotlin.idea.test.ModuleKind import org.jetbrains.kotlin.idea.test.configureAs @@ -29,7 +29,7 @@ public abstract class AbstractDecompiledTextFromJsMetadataTest(baseDirectory: St NavigateToDecompiledLibraryTest.getKjsmFile(TEST_PACKAGE, getTestName(false), myModule!!) protected override fun checkPsiFile(psiFile: PsiFile) = - assertTrue(psiFile is KotlinJavascriptMetaFile, "Expecting decompiled kotlin javascript file, was: " + psiFile.javaClass) + assertTrue(psiFile is KtDecompiledFile, "Expecting decompiled kotlin javascript file, was: " + psiFile.javaClass) override fun setUp() { super.setUp()